SOLVED Hide description element using MessageData::CoreMessage() function

Hello,
I am aware of hiding elements using NodeData::GetDDescription() function, but I need to hide the elements using MessageData::CoreMessage() function.
My scenario is like this:
I am working on an external renderer, and on my render settings when clicking "Render" Button, I would hide that and show "Abort Render" button instead. I have handled this using NodeData::GetDDescription(), but now when the Rendering is finished I want to Hide "Abort Render" button and instead show "Render" button again.
Since I know when the rendering is finished (Adding a special event with ID = DL_RENDER_FINISHED "SpecialEventAdd(RENDERING_FINISHED);", and I can catch this event using CoreMessage() function, I thought it might possible to hide the elements on this function too.

Bool RenderManager::CoreMessage(Int32 id, const BaseContainer &bc)
{
	if (id == RENDERING_FINISHED) 
        {
	     ApplicationOutput("Finished"); //This get's shown exactly after rendering is finished so I know I get the message when I need it. 
             //Need a way to hide an element and show another instead.??
        }
}

Is there any way I can achieve this?
Thank you.

hi,

I'm a bit surprised that your render can be triggered from a NodeData (but why not)
But i don't understand why you can't use GetDDescription to update your node.

That's what i did (in a probably too naive way) but you got the idea. I just got a boolean display_aboard on my ObjectData and i switch it as i needed.
If i presse the button, i switch and i set dirty my node, if i receive the message that the render is finished (or stopped) i set my bool to false and i SetDirty my node.

static const Int32 g_pc12584ButtonID = 1000;

	
class pc12584_object : public ObjectData
{

	INSTANCEOF(pc12584_object, ObjectData);

public:
	static NodeData* Alloc() { return NewObjClear(pc12584_object); };

	Bool Init(GeListNode* node) override
	{
		display_aboard = false;
		return true;
	}

	BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) override
	{
		BaseObject* null = BaseObject::Alloc(Onull);
		return null;
	}


	Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) override
	{
		
		if (!description->LoadDescription(Obase))
			return false;
		

		const DescID* singleid = description->GetSingleDescID();
		const Int32 ID = g_pc12584ButtonID;
		const DescID cid = DescLevel(ID, DTYPE_BUTTON, 0);

		if (!singleid || cid.IsPartOf(*singleid, nullptr))
		{
			BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);

			bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
			if (display_aboard)
				bc.SetString(DESC_NAME, "Aboard Render"_s);
			else
				bc.SetString(DESC_NAME, "Render"_s);
			bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF);
			bc.SetInt32(DESC_SCALEH, 1);

			description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES));
		}

		flags |= DESCFLAGS_DESC::LOADED;
		
		return SUPER::GetDDescription(node, description, flags);
	}


	Bool Message(GeListNode* node, Int32 type, void* data) override
	{
		switch (type)
		{
		case MSG_DESCRIPTION_COMMAND:
		{
			DescriptionCommand* dc = (DescriptionCommand*)data;

			const Int32 id = dc->_descId[0].id;

			if (id == g_pc12584ButtonID)
			{
				display_aboard = !display_aboard;
				node->SetDirty(DIRTYFLAGS::DESCRIPTION);
			}
			break;
		}
		case g_pc12584Message:
		{
			display_aboard = false;
			node->SetDirty(DIRTYFLAGS::DESCRIPTION);
			break;
		}
		}

		return SUPER::Message(node, type, data);
	};

private:
	Bool display_aboard = false;


};


// function to send a message to the ObjectData.
static maxon::Result<void> PC12854_Message(BaseDocument* doc)
{

	iferr_scope;
	// update the first object 
	BaseObject* op = doc->GetFirstObject();
	if (op == nullptr)
		return maxon::NullptrError(MAXON_SOURCE_LOCATION);

	op->Message(g_pc12584Message);


	return maxon::OK;
}


Cheers,
Manuel

hi,

it's a bit strange that you are talking about GetDDescription witch is for NodeData and CoreMessage witch is more about a GeDialog.

If you are inside a NodeData you should react to a message received and set a flag and the NodeData dirty.

display_aboard = false;
node->SetDirty(DIRTYFLAGS::DESCRIPTION);

Setting the node dirty will trigger the GetDDescription function and an update of the UI.

If you are in a GeDialog things are manage with groups and LayoutFlushGroup.

Basically you flush the group and recreate it.

We got example of dynamic GeDialog here and also for Descriptions

Cheers,
Manuel

hi @m_magalhaes
Yes I am talking about NodeData and the CoreMessage used is not GeDialog::CoreMessage() but is a MessagePlugin MessageData::CoreMessage() which I am using to receive core messages which in this case are the SpecialEvents I have added when clicking Render Button as in below.

Bool RenderSettings::Message(GeListNode* i_node, Int32 i_type, void* i_data)
{
        DescriptionCommand* dc = (DescriptionCommand*)i_data;
	BaseContainer* dldata = ((BaseVideoPost*)i_node)->GetDataInstance();
	switch (i_type)
	{
	case MSG_DESCRIPTION_COMMAND:
	{
                switch (dc->_descId[0].id)
		{
		case RENDER_BUTTON:
		  SpecialEventAdd(START_RENDER);
		  break;
                //Other cases
                 }
        }
}

Now I am catching this special events using CoreMessage function of MessageData. I am doing this way because I need an event telling me when the rendering is finished and this has nothing to do with a NodeData(Which tells me when the rendering starts) or GeDialog as none of this tells me how long does it take for the rendering to finish.

Hi,

I do not fully understand what you are trying to do, but @m_magalhaes already gave you the crucial hint IMHO. You can flag your node as description dirty via SetDirty(DIRTYFLAGS::DESCRIPTION) and then react there to whatever you want to react to. AFAIK it is impossible to modify a description of a node outside of GetDDescription and have these description changes properly reflected in the GUI of the node. So unless I am wrong about this, you won't have any choice but to go this route.

Cheers,
zipit

hi,

I'm a bit surprised that your render can be triggered from a NodeData (but why not)
But i don't understand why you can't use GetDDescription to update your node.

That's what i did (in a probably too naive way) but you got the idea. I just got a boolean display_aboard on my ObjectData and i switch it as i needed.
If i presse the button, i switch and i set dirty my node, if i receive the message that the render is finished (or stopped) i set my bool to false and i SetDirty my node.

static const Int32 g_pc12584ButtonID = 1000;

	
class pc12584_object : public ObjectData
{

	INSTANCEOF(pc12584_object, ObjectData);

public:
	static NodeData* Alloc() { return NewObjClear(pc12584_object); };

	Bool Init(GeListNode* node) override
	{
		display_aboard = false;
		return true;
	}

	BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) override
	{
		BaseObject* null = BaseObject::Alloc(Onull);
		return null;
	}


	Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) override
	{
		
		if (!description->LoadDescription(Obase))
			return false;
		

		const DescID* singleid = description->GetSingleDescID();
		const Int32 ID = g_pc12584ButtonID;
		const DescID cid = DescLevel(ID, DTYPE_BUTTON, 0);

		if (!singleid || cid.IsPartOf(*singleid, nullptr))
		{
			BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);

			bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
			if (display_aboard)
				bc.SetString(DESC_NAME, "Aboard Render"_s);
			else
				bc.SetString(DESC_NAME, "Render"_s);
			bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF);
			bc.SetInt32(DESC_SCALEH, 1);

			description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES));
		}

		flags |= DESCFLAGS_DESC::LOADED;
		
		return SUPER::GetDDescription(node, description, flags);
	}


	Bool Message(GeListNode* node, Int32 type, void* data) override
	{
		switch (type)
		{
		case MSG_DESCRIPTION_COMMAND:
		{
			DescriptionCommand* dc = (DescriptionCommand*)data;

			const Int32 id = dc->_descId[0].id;

			if (id == g_pc12584ButtonID)
			{
				display_aboard = !display_aboard;
				node->SetDirty(DIRTYFLAGS::DESCRIPTION);
			}
			break;
		}
		case g_pc12584Message:
		{
			display_aboard = false;
			node->SetDirty(DIRTYFLAGS::DESCRIPTION);
			break;
		}
		}

		return SUPER::Message(node, type, data);
	};

private:
	Bool display_aboard = false;


};


// function to send a message to the ObjectData.
static maxon::Result<void> PC12854_Message(BaseDocument* doc)
{

	iferr_scope;
	// update the first object 
	BaseObject* op = doc->GetFirstObject();
	if (op == nullptr)
		return maxon::NullptrError(MAXON_SOURCE_LOCATION);

	op->Message(g_pc12584Message);


	return maxon::OK;
}


Cheers,
Manuel