Solved Undo for GeDialog (GUI)?

Is there a way to undo selection for GeDialog(GUI)?

You can see the problem here:
https://www.dropbox.com/s/bycx4xjsv07a7ez/c4d205_undo_for_gedialog_gui.mp4?dl=0

As you can see, I changed the FK to IK and it is reflected in the viewport.
I pressed Ctrl+Z and it is reflected in the viewport (i.e reverted back to FK) but the GUI is still in IK selection.

There is an existing thread that says it is not possible. Is this still relevant today?

If so, are there any other alternatives?

I was thinking of having to reinitialize values through InitValues() for every 5 second so that the UI will sync to the viewport but I'm not sure if this is a standard.

Any thoughts?

Thank you

Hi @bentraje!
I found this documentation in the C++ manual that says:

"To start and end an undo based on some interaction in a GeDialog the messages BFM_INTERACTSTART and BFM_INTERACTEND can be used."

I tried this in the GeDialog and got a TypeError:

    def Message(self, msg, result):
        if msg.GetId()==c4d.BFM_INTERACTSTART:
            print("Interact Start")
            doc.AddUndo(c4d.UNDOTYPE_CHANGE,self)
        elif msg.GetId()==c4d.BFM_INTERACTEND:
            print("Interact End")
        return gui.GeDialog.Message(self, msg, result)

TypeError: argument 2 must be c4d.GeListNode

I don't think I'm setting up the Undo correctly because what can be passed to doc.AddUndo from the GeDialog that is GeListNode? Without the doc.AddUndo line, those message conditionals do work.

hello,

You GUI should update when something change in the scene.
In this case you can use CoreMessage to trigger an update function if something have change.
Check the value and update your GeDialog accordingly

class MyDialog(c4d.gui.GeDialog):

    def __init__(self):
        self.comboBox = 2000
        self.FK = 2001
        self.IK = 2002

    def CreateLayout(self):
        
        cycle = self.AddComboBox(self.comboBox, c4d.BFH_SCALEFIT, 100, 10, False, True);
        self.AddChild(self.comboBox, self.FK, "FK");
        self.AddChild(self.comboBox, self.IK, "IK");
                
        return True

    def InitValues(self):
        self.CheckValues()
        return True
    
    def FindTag(self):
        # retrieves the tag where we want to change the value of the field
        doc = c4d.documents.GetActiveDocument()
        if doc is None:
            raise ValueError("no active document")
        op = doc.GetActiveObject()
        if op is None:
            raise ValueError("no active Object")
        tag = op.GetTag(1019561)
        if tag is None:
            raise ValueError("no IK tag found on this object")
        return tag

    def CheckValues(self):
        # Check the value of the field of the tag and set the value of the gadget
        tag = self.FindTag()

        if tag[c4d.ID_CA_IK_TAG_IKFK] == 1.0:
            self.SetInt32(self.comboBox, self.FK)
        else:
            self.SetInt32(self.comboBox, self.IK)
    

    def Command(self, id, msg):
        # Reacts to the change of the combo box, update the tag value.
        if id == self.comboBox:
            value = self.GetInt32 (self.comboBox)
            if value == self.FK:
                self.FindTag()[c4d.ID_CA_IK_TAG_IKFK] = 1.0            
            else:
                self.FindTag()[c4d.ID_CA_IK_TAG_IKFK] = 0.0
        c4d.EventAdd()
        return True

    def CoreMessage(self, id, msg):
        # If something have change in the scene, check the values 
        if (id == c4d.EVMSG_CHANGE):
            self.CheckValues()

        return True

Cheers,
Manuel

MAXON SDK Specialist

MAXON Registered Developer

@blastframe @m_magalhaes

Thanks for the response and the confirmation that Undo is not included in the GeDialog(GUI).

That said the supplied code works on my use case.

Thanks again!