Solved Checking for ALT GetInputState() issue

I have a command plugin with a slider to move the distance between planes.
If the user presses ALT and move the slider, I update the position of place realtime.
Input and ALT checking is done with below code.

Checking for ALT is oke, but when there is no parent and a message is given to the user, it looks like the GetInputState() is still running and the slider is moved.

How can I 'stop' the GetInputState() in case of an error?
I hope I make myself clear.

64ddfda6-40cb-4167-9264-5a4e01a9c665-image.png

if (id == UI_SPACING):                   
            self.Spacing  = self.GetInt32(UI_SPACING)     
         
            msg=c4d.BaseContainer()        
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.KEY_ALT, msg):
        
                if msg[c4d.BFM_INPUT_VALUE]:    # only dynamic update if Alt is pressed                                       
                    parent = doc.GetActiveObject()        
                    if (not(parent)):                           
                        gui.MessageDialog('Please select a cloner!')         
                        return True                                          
                    else:        
                        self.DoHorizontalSpacing(parent, self.Spacing)   
                                   
            return True
        
        `

Just checked with development team, and this is a bug as this is something we don't really support and the slider having a default behavior for when alt is currently executed. So far there is no workaround, so the best way to proceed would be to create your own alert windows like so:

import c4d


PLUGINSTRING = "Alt test"
UI_SPACING = 15048

class AlertDialog(c4d.gui.GeDialog):
    
    @staticmethod
    def Create(msg):
        alertDlg = AlertDialog(msg)
        
        alertDlg.Open(c4d.DLG_TYPE_MODAL, defaultw=0, defaulth=0)
        return alertDlg
    
    def __init__(self, msg):
        self.message = msg
        
    def CreateLayout(self):
        self.AddStaticText(id=1000, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, initw=150, name=self.message)
        self.AddDlgGroup(c4d.DLG_OK)
        return True
        
    def Command(self, messageId, bc):
        if messageId == c4d.DLG_OK:
            self.Close()
        return True

class AltTestDialog(c4d.gui.GeDialog):

    def CreateLayout(self):
        self.SetTitle(PLUGINSTRING)

        self.AddStaticText(id=1001, flags=c4d.BFH_MASK, initw=150, name="Spacing", borderstyle=c4d.BORDER_NONE)
        self.AddEditSlider(UI_SPACING, c4d.BFH_SCALEFIT, initw=80, inith=0)
        return True


    def Command(self, gadgetId, msg):
        doc = c4d.documents.GetActiveDocument()

        if gadgetId == UI_SPACING:
            self.Spacing  = self.GetInt32(UI_SPACING)

            newMsg = c4d.BaseContainer()
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.KEY_ALT, newMsg):

                if newMsg[c4d.BFM_INPUT_VALUE]:    # only dynamic update if Alt is pressed
                    parent = doc.GetActiveObject()
                    if not parent:
                        AlertDialog.Create('Please select a cloner!')
                        return True

        return True


def main():
    global dlg
    # Creates a new instance of the GeDialog
    dlg = AltTestDialog()

    # Opens the GeDialog, since it's open it as Modal, it block Cinema 4D
    dlg.Open(c4d.DLG_TYPE_ASYNC, defaultw=300, defaulth=50)


if __name__ == "__main__":
    main()

Cheers,
Maxime

Hi @pim sorry I was busy the last days, regarding your question keep in mind that returning true cancel all others messages so please forward the message at the end so all operations like drag operation are performed correctly.

1 week ago the question on How to detect CTRL being pressed in a GeDialog was asked, and the correct way is to check for BFM_INPUT_QUALIFIER and not BFM_INPUT_VALUE

If it does not work, then I will ask you to provide a complete example.
Cheers,
Maxime.

@m_adam

Thanks for replying.
Let me first of all explain in a bit more detail, what happens.
I have a input field that is handle in Command().
I test for ALT input, in which case I want to space some planes.
Before I space the planes, I test for a selected object.
If not, then I give out an error message.

496e65be-52d4-4dc2-bf98-ff7d5b55c74c-image.png
However, after giving out the error message, the input field is still active, so when I move the cursor, the input value is changed and I cannot select an object.
I must click the input field first before I can select.

I also noticed from your example that you check Alt in Message() and not in Command().
Here the code.

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

PLUGINSTRING = "Alt test"
PLUGIN_ID = 105284244      

UI_SPACING              = 15048
    
class AltTestDialog(c4d.gui.GeDialog):

    def CreateLayout(self):
        self.SetTitle(PLUGINSTRING) 

        self.AddStaticText(id=1001, flags=c4d.BFH_MASK, initw=150, name="Spacing", borderstyle=c4d.BORDER_NONE)  
        self.AddEditSlider(UI_SPACING, c4d.BFH_SCALEFIT, initw=80, inith=0)
        return True


    def Command(self, id, msg):   
        doc = documents.GetActiveDocument() 
        
        if (id == UI_SPACING):                   
            self.Spacing  = self.GetInt32(UI_SPACING)     
 
            msg=c4d.BaseContainer()        
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.KEY_ALT, msg):
        
                if msg[c4d.BFM_INPUT_VALUE]:    # only dynamic update if Alt is pressed                                       
                    parent = doc.GetActiveObject()  
                    if (not(parent)):                           
                        gui.MessageDialog('Please select a cloner!')                        
                        return True                                          
                    else:        
                        #self.DoHorizontalSpacing(parent, self.Spacing)   
                        pass
                                   
            return True 

class AltTest(c4d.plugins.CommandData):

    dialog = None

    def Init(self, op):
        return True

    def Message(self, type, data):
        return True

    def Execute(self, doc):
        if self.dialog is None:
            self.dialog = AltTestDialog()
        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=160)

        
if __name__ == '__main__':
    bmp = c4d.bitmaps.BaseBitmap()
    dir, file = os.path.split(__file__)
    fn = os.path.join(dir, "res", "Icon.tif")
    bmp.InitWith(fn)
    
    okyn = plugins.RegisterCommandPlugin(PLUGIN_ID, PLUGINSTRING, 0, bmp, PLUGINSTRING, AltTest())
    if (okyn): 
        print (PLUGINSTRING + " initialized.")
    else: 
        print ("Error initializing " + PLUGINSTRING )

Hi thanks a lot, I'm now able to reproduce the issue, this may take some time (if this is even possible) to provide a workaround. But will for sure find a way to achieve that within this week.

Cheers,
Maxime.

Just checked with development team, and this is a bug as this is something we don't really support and the slider having a default behavior for when alt is currently executed. So far there is no workaround, so the best way to proceed would be to create your own alert windows like so:

import c4d


PLUGINSTRING = "Alt test"
UI_SPACING = 15048

class AlertDialog(c4d.gui.GeDialog):
    
    @staticmethod
    def Create(msg):
        alertDlg = AlertDialog(msg)
        
        alertDlg.Open(c4d.DLG_TYPE_MODAL, defaultw=0, defaulth=0)
        return alertDlg
    
    def __init__(self, msg):
        self.message = msg
        
    def CreateLayout(self):
        self.AddStaticText(id=1000, flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, initw=150, name=self.message)
        self.AddDlgGroup(c4d.DLG_OK)
        return True
        
    def Command(self, messageId, bc):
        if messageId == c4d.DLG_OK:
            self.Close()
        return True

class AltTestDialog(c4d.gui.GeDialog):

    def CreateLayout(self):
        self.SetTitle(PLUGINSTRING)

        self.AddStaticText(id=1001, flags=c4d.BFH_MASK, initw=150, name="Spacing", borderstyle=c4d.BORDER_NONE)
        self.AddEditSlider(UI_SPACING, c4d.BFH_SCALEFIT, initw=80, inith=0)
        return True


    def Command(self, gadgetId, msg):
        doc = c4d.documents.GetActiveDocument()

        if gadgetId == UI_SPACING:
            self.Spacing  = self.GetInt32(UI_SPACING)

            newMsg = c4d.BaseContainer()
            if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.KEY_ALT, newMsg):

                if newMsg[c4d.BFM_INPUT_VALUE]:    # only dynamic update if Alt is pressed
                    parent = doc.GetActiveObject()
                    if not parent:
                        AlertDialog.Create('Please select a cloner!')
                        return True

        return True


def main():
    global dlg
    # Creates a new instance of the GeDialog
    dlg = AltTestDialog()

    # Opens the GeDialog, since it's open it as Modal, it block Cinema 4D
    dlg.Open(c4d.DLG_TYPE_ASYNC, defaultw=300, defaulth=50)


if __name__ == "__main__":
    main()

Cheers,
Maxime

Great, thank you
Glad I can help to improve this great program.