Hi,
sorry for the late reply. Just got to test out your fix and everything works now. Thank you very much for your persistence!
cheers,
Lorenz
Hi,
sorry for the late reply. Just got to test out your fix and everything works now. Thank you very much for your persistence!
cheers,
Lorenz
Hi @ferdinand,
thank you very much for looking into my issue this thoroughly and providing such a helpful reply
I will wait and see if/when the bug gets fixed. Meanwhile I will look into creating a custom class.
kind regards,
Lorenz
@ferdinand thank you for your quick reply! I have tried your suggestions unfortunately to no avail.
I have uploaded a repro case here based on the c4d_sdk simplematerial. I hope this is an easily compilable version for you.
kind regards,
Lorenz
I am struggling with getting a LinkBox UI to update when setting the content of the LinkBox from code. Specifically I can not get the arrow on the left of the LinkBox to appear that allows the user to edit the content of the LinkBox.
As soon as I interact with any other element on the UI the LinkBox refreshes and the arrow appears, but I would like to have it happen right away.
Attached is the code that creates and fills the LinkBox as well as the code that dynamically creates the Linkbox when GetDDescription is called.
Bool Material::Message(GeListNode* node, Int32 type, void* data)
{
case MSG_DESCRIPTION_COMMAND:
{
DescriptionCommand* dc = (DescriptionCommand*) data;
const Int32 msg_id = GetDescriptionCommandMessageId(dc);
switch (msg_id)
{
case:
(MATERIALGROUP_DYNAMIC +
MATERIALELEMENTS::ADD_MATERIAL_BUTTON))
{
auto doc = mat->GetDocument();
if (doc == nullptr)
{
return;
}
auto* material = BaseMaterial::Alloc(MAT_ID_material);
if (!material)
return;
doc->StartUndo();
doc->InsertMaterial(material);
EventAdd();
doc->AddUndo(UNDOTYPE_NEWOBJ, material);
doc->EndUndo();
int index_base = 0;
{
index_base = MATERIALGROUP_DYNAMIC;
BaseContainer* bc = material->GetDataInstance();
bc->SetLink(index_base + MATERIALELEMENTS::SHADER_LINK_MATERIAL, material);
}
//FAILED Attempts to get the UI to update so far below
C4dMainThreadDispatcher::enqueueAction([node]() {
node->SetDirty(DIRTYFLAGS::DESCRIPTION);
node->SetDirty(DIRTYFLAGS_ALL);
EventAdd(EVENT_FORCEREDRAW);
});
node->SetDirty(DIRTYFLAGS::DESCRIPTION);
node->SetDirty(DIRTYFLAGS_ALL);
EventAdd(EVENT_FORCEREDRAW);
break;
}
}
}
}
Bool Material::GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags)
{
if (!description->LoadDescription(material))
return false;
int group_id = MATERIALGROUP_DYNAMIC;
BaseContainer shader_group_bc = GetCustomDataTypeDefault(DTYPE_GROUP);
{
shader_group_bc.SetInt32(DESC_COLUMNS, 2);
shader_group_bc.SetInt32(DESC_SCALEH, 1);
description->SetParameter(DescLevel(group_id + MATERIALELEMENTS::SHADER_LINK_PARENT, DTYPE_GROUP, 0), shader_group_bc, group_id);
}
{
BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BASELISTLINK);
bc.SetString(DESC_NAME, "Shader"_s);
bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LINKBOX);
//list of allowed types
BaseContainer ac;
ac.SetInt32(Mmaterial, 1);
bc.SetContainer(DESC_ACCEPT, ac);
description->SetParameter(DescLevel(group_id + MATERIALELEMENTS::SHADER_LINK_MATERIAL, DTYPE_BASELISTLINK, 0),
bc, group_id + MATERIALELEMENTS::SHADER_LINK_PARENT);
}
{
BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON);
bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON);
bc.SetString(DESC_NAME, "Create Material"_s);
bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF);
description->SetParameter(DescLevel(group_id + MATERIALELEMENTS::ADD_MATERIAL_BUTTON, DTYPE_BUTTON, 0), bc,
group_id + MATERIALELEMENTS::SHADER_LINK_PARENT);
}
flags |= DESCFLAGS_DESC_LOADED;
return SUPER::GetDDescription(node, description, flags);
}
As you can see I've tried calling EventAdd both on the C4D main thread as well as directly as well es setting some dirty flags that should trigger a redraw. From debugoutput I can tell, that GetDDescription does get called even multiple times after clicking on the "add Material" button.
Any suggestions are welcome
cheers,
Lorenz