Solved Unusual Dynamic Inputs from GeDialog


I am trying to create a dialog that list objects in the scene with specific parameters. However, it somehow skips some rows unexpectedly. You can see an illustration of the problem here:

Is there a way around this?

You can check the working code here. The glitch happens in the line for idx, object in enumerate(self.objectsList) block:

import c4d
import os
from c4d import gui, plugins, bitmaps, utils, documents

PLUGIN_ID   = 1811321

class MyDialog(gui.GeDialog):

    def __init__(self):
        # Be sure that we have the object list before building the UI
        # as InitValues is called after CreateLayout()
        self.objectsList = []
        self.object_count = len(self.objectsList)

    def InitValues(self):
        # Use to Init and in Case of an Update needed.
        self.objectsList = []
        self.object_count = len(self.objectsList)
        return True

    def GetNextObject(self, op ):
        # use a non-recursive method to iterate the hierarchy
        # allow to not hit the recursive stack limit.

        if not op:
            return None

        if op.GetDown():
            return op.GetDown()

        while not op.GetNext() and op.GetUp():
            op = op.GetUp()

        return op.GetNext()

    def GetAllObjects(self):

        doc = c4d.documents.GetActiveDocument()
        op = doc.GetFirstObject()

        self.objectsList = []

        while op:
            op = self.GetNextObject(op)

    def Update(self): # NEW CODE

        if self.object_count == 0:
            self.AddStaticText(0, c4d.BFH_CENTER, name="There are no objects in the scene")

        if self.object_count > 0 :

            self.AddStaticText(0, 1, name="Name")
            self.AddStaticText(0, 0, name="Enable")
            self.AddStaticText(0, 0, name="Xray")


            for idx, object in enumerate(self.objectsList): # where the glitch happens

                text_ID = (idx) * 1
                enable_ID = (idx) * 2
                xray_ID = (idx) * 3

                self.AddEditText(text_ID, flags=c4d.BFH_LEFT, initw=200, editflags=c4d.EDITTEXT_HELPTEXT)
                self.AddCheckbox(enable_ID, flags=c4d.BFH_LEFT, initw=20, inith=10, name="Enable")
                self.AddCheckbox(xray_ID, flags=c4d.BFH_LEFT, initw=20, inith=10, name="Xray")

                self.SetString(text_ID, value=object.GetName())
                self.SetInt32(enable_ID, value=object[c4d.ID_BASEOBJECT_GENERATOR_FLAG])
                self.SetInt32(xray_ID, value=object[c4d.ID_BASEOBJECT_XRAY])


    def CreateLayout(self):

        print "nombre d'objet ", self.object_count
        self.GroupBegin(id=1001, flags=c4d.BFH_FIT, cols=3, rows=20, title="Rigging")



        return True

    def Command(self, id, msg):

        return True

    def CoreMessage(self, id, msg):

        if id == c4d.EVMSG_CHANGE: 


        return True

class MyMenuPlugin(plugins.CommandData):

    dialog = None
    def Execute(self, doc):

        if self.dialog is None:
            self.dialog = MyDialog()

        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=200, defaulth=150, xpos=-1, ypos=-1)

if __name__ == "__main__":

    plugins.RegisterCommandPlugin(PLUGIN_ID, "test_dynamic_update",0, None, "test_dynamic_update", MyMenuPlugin())

Thank you for looking at my problem.

@bentraje said in Unusual Dynamic Inputs from GeDialog:

           text_ID = (idx) * 1
            enable_ID = (idx) * 2
            xray_ID = (idx) * 3

You actually overwrite the data yourself.

idx at 0, so text_ID = 0, enable_ID = 0, xray_ID = 0
idx at 1, so text_ID = 1, enable_ID = 2, xray_ID = 3
idx at 2, so text_ID = 2, enable_ID = 4, xray_ID = 6
idx at 3, so text_ID = 3, enable_ID = 6, xray_ID = 9

So please rethink your algorithm, the easier way is to have a base ID for all tree and add the current index like

text_ID = 100000 + idx
enable_ID = 200000 + idx
xray_ID = 300000 + idx


Thanks for the help. Works as expected.
Have a great day ahead!