Solved How to prevent a LinkBoxGui from accepting an object?

Hello,
I want my LinkBoxes to refuse an object that is already linked by another LinkBox. How can I do this?

I came up with a simple script demonstrating where I've gotten stuck:

import c4d
from c4d import gui
import c4d.plugins

LINKBOX_GUI_1 = 2001
LINKBOX_GUI_2 = 2002

class LinkBoxDlg(c4d.gui.GeDialog):
    doc = c4d.documents.GetActiveDocument()

    def __init__(self):
        self.linkboxes = list()
        
    def CreateLayout(self):
        if self.GroupBegin(2003, c4d.BFH_SCALEFIT, 1, 2, "", 0, 0):
            self.GroupBorderSpace(10, 10, 10, 10)
            if self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 1, "", 0, 0):
                self.AddStaticText(2004, c4d.BFH_LEFT, 0, 0, "Object 1")
                link1 = self.AddCustomGui(LINKBOX_GUI_1, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_SCALEFIT, 0, 0)
                self.linkboxes.append(link1)
            self.GroupEnd()
            if self.GroupBegin(2005, c4d.BFH_SCALEFIT, 2, 2, "", 0, 0):
                self.AddStaticText(0, c4d.BFH_LEFT, 0, 0, "Object 2")
                link2 = self.AddCustomGui(LINKBOX_GUI_2, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_SCALEFIT, 0, 0)
                self.linkboxes.append(link2)
            self.GroupEnd()
        self.GroupEnd()
        return True
    
    def Message (self, msg, result):
        if msg.GetId() == c4d.MSG_DESCRIPTION_CHECKDRAGANDDROP:
            print "*"*50
            print "accept: %s"%msg[c4d.LINKBOX_ACCEPT_MESSAGE_ACCEPT]
            print "control_id: %s"%msg[c4d.LINKBOX_ACCEPT_MESSAGE_CONTROL_ID] # How do I use this control ID to reference the linkbox in the GeDialog?
            print "element: %s"%msg[c4d.LINKBOX_ACCEPT_MESSAGE_ELEMENT] # How do I use this pointer to find the object in the document?
            print "msg_type: %s"%msg[c4d.LINKBOX_ACCEPT_MESSAGE_TYPE]
            print "*"*50
            msg[c4d.LINKBOX_ACCEPT_MESSAGE_ACCEPT] = False # Testing editing the message. Why doesn't this affect the linkbox?
        return gui.GeDialog.Message(self, msg, result)

    def Command(self, id, msg):
        if id == LINKBOX_GUI_1:
            print msg[c4d.BFM_ACTION_VALUE]
        elif id == LINKBOX_GUI_2:
            print msg[c4d.BFM_ACTION_VALUE]
        return True

def main():
    global dlg
    dlg = LinkBoxDlg()
    dlg.Open(c4d.DLG_TYPE_ASYNC, defaultw=300, defaulth=100)

if __name__=='__main__':
    main()

I am not understanding how to use the pointers or how to edit the MSG_DESCRIPTION_CHECKDRAGANDDROP message. Once I know how to get the linkbox's proposed linked object and how to accept/refuse, I can check the other linkboxes' values to determine whether or not to proceed with the object.

Thank you!

Hi,

I do not know this for sure, but I would assume that MSG_DESCRIPTION_CHECKDRAGANDDROP is intended - as its name implies - to be used in description resources only. If you check the corresponding message data in C++, you will also see, that it is clearly tied to descriptions. The message being sent does not necessarily mean, that Cinema will also process your response. There is a lot of stuff that only kind of works in GeDialog.

Cheers,
zipit

MAXON SDK Specialist
developers.maxon.net

Why don't you just check the value stored in the gadget in your Command() function (GetLink()) and change it, if it is not OK (SetLink())?

@PluginStudent Thanks for the idea of how to solve this! I was doing what you described before posting my example, but probably making it too complicated. The documentation for the Link gadget describes the pointer LINKBOX_ACCEPT_MESSAGE_ACCEPT as 'A pointer to a boolean value. Set this value to true to accept the object.' so that sounded like what I needed. I've rewritten the approach you described and have it seemingly working.