Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Hide description element using MessageData::CoreMessage() function

    Cinema 4D SDK
    r21
    3
    5
    801
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • O
      Ogers
      last edited by Ogers

      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.

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by 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

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • O
          Ogers
          last edited by Ogers

          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.

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by

            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

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • ManuelM
              Manuel
              last edited by

              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

              MAXON SDK Specialist

              MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • First post
                Last post