Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Checking for ALT GetInputState() issue

    Cinema 4D SDK
    python 2023
    2
    6
    1.1k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • P
      pim
      last edited by pim

      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
              
              `
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        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.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        P 1 Reply Last reply Reply Quote 0
        • P
          pim @m_adam
          last edited by

          @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 )
          
          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by

            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.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by

              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

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • P
                pim
                last edited by

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

                1 Reply Last reply Reply Quote 0
                • P pim referenced this topic on
                • First post
                  Last post