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



  • 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.


Log in to reply