Message when leaving an Edit Text



  • Hi!
    In Javascript there's an event onfocusout triggered when the user has left an editable text input.

    Similarly, I want to execute a function when the user leaves the EditText (by Tab or mouse) of my GeDialog. I thought maybe I could listen for the message with the ID of c4d.BFM_LOSTFOCUS, but that seems to be when the entire GeDialog loses focus (similar to c4d.BFM_ACTIVE_CHG). I also tried c4d.BFM_INTERACTEND but that happens after every input, including keystrokes. How can I listen for when a user leaves an EditText please? Thank you!

    ids = [c4d.BFM_MARKFOCUS,c4d.BFM_ACTIVE_CHG,c4d.BFM_SETFOCUS,c4d.BFM_INTERACTEND,\
            c4d.BFM_ACTION,c4d.BFM_LOSTFOCUS]
    
    def Message(self, msg, result):
        if msg.GetId() in self.ids:
            for cid,val in msg:
                print cid,val
                    
        return c4d.gui.GeDialog.Message(self, msg, result)
    


  • @blastframe

    Maybe not the best solution, but I have tried the following code (C++) and it displays a text in the console when the Edit Text gets the focus, and displays another text when it loses focus.

    Note that 'mActiveEdit' is a custom bool variable, member of MyDialog class,
    and ID_TEXTEDIT is the Edit Text gadget id.

    Int32 MyDialog::Message(const BaseContainer& msg, BaseContainer& result)
    {
    	if (IsActive(ID_TEXTEDIT) && !mActiveEdit)
    	{
    		ApplicationOutput("Activate TextEdit");
    		mActiveEdit = true;
    	}
    	if (!IsActive(ID_TEXTEDIT) && mActiveEdit)
    	{
    		ApplicationOutput("TextEdit was active");
    		mActiveEdit = false;
    	}
    
    


  • @blastframe

    Maybe not the best solution, but I have tried the following code (C++) and it displays a text in the console when the Edit Text gets the focus, and displays another text when it loses focus.

    Note that 'mActiveEdit' is a custom bool variable, member of MyDialog class,
    and ID_TEXTEDIT is the Edit Text gadget id.

    Int32 MyDialog::Message(const BaseContainer& msg, BaseContainer& result)
    {
    	if (IsActive(ID_TEXTEDIT) && !mActiveEdit)
    	{
    		ApplicationOutput("Activate TextEdit");
    		mActiveEdit = true;
    	}
    	if (!IsActive(ID_TEXTEDIT) && mActiveEdit)
    	{
    		ApplicationOutput("TextEdit was active");
    		mActiveEdit = false;
    	}
    
    


  • @C4DS This solution works for me! Unless someone from the SDK team advises against for some reason, I'll mark yours as the correct answer. Here's a Python version of your code:

    import c4d
    from c4d import gui
    
    PLUGIN_ID = 9999996 #Test ID
    
    class My_Dlg(gui.GeDialog):
        mActiveEdit1 = False
        mActiveEdit2 = False
        ID_TEXTEDIT1 = 1001
        ID_TEXTEDIT2 = 1002
    
        def CreateLayout(self):
            self.SetTitle("Edit Text Focus Events")
            if self.GroupBegin(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALE |\
                c4d.BFV_CENTER, initw=0, inith=0, cols=1, rows=1, title=""):
                self.GroupBorderSpace(20, 20, 20, 20) #left, top, right, bottom
                self.AddEditText(self.ID_TEXTEDIT1, c4d.BFH_SCALEFIT, 90, 0)
                self.AddEditText(self.ID_TEXTEDIT2, c4d.BFH_SCALEFIT, 90, 0)
            self.GroupEnd()
    
            return True
    
        def ActivateEditText(self,id,active):
            activeBool = getattr(self,active)
            if self.IsActive(id) and not activeBool:
                print("Activate TextEdit: %s"%id)
                setattr(self,active,True)
            elif not self.IsActive(id) and activeBool:
                print("TextEdit %s was active"%id)
                setattr(self,active,False)
    
        def Message(self, msg, result):
            self.ActivateEditText(self.ID_TEXTEDIT1,"mActiveEdit1")
            self.ActivateEditText(self.ID_TEXTEDIT2,"mActiveEdit2")
            return c4d.gui.GeDialog.Message(self, msg, result)
    
        def Command(self, id, msg):
            return True
    
    def main():
        global myDlg
        myDlg = My_Dlg()
        myDlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2,\
            pluginid=PLUGIN_ID, defaultw=300, defaulth=200)
    
    if __name__=='__main__':
        main()
    

    Thanks again!



  • While the topic is set to solved.

    I confirm there is no built-in way for doing what you are asking for.
    Maybe it would have more sense to create a Timer, instead of checking in Message (Since Message is called very very often so it may be more interesting to check only each second / 0.5 sec)

    Cheers,
    Maxime.



  • @m_adam Great idea! I'll use a Timer 😃 Thanks Maxime!


Log in to reply