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

    Avoid: IsActive()

    Cinema 4D SDK
    python classic api
    3
    10
    1.2k
    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.
    • lasselauchL
      lasselauch
      last edited by

      Hi there,

      I'm wondering, is it possible to avoid IsActive() in Message to support older C4D-Versions.

      In another thread: https://developers.maxon.net/forum/topic/11462/understanding-setcommanddragid/4 we've talked about the ability to drag BitmapButtons into the layout via SetCommandDragId.

          def CreateLayout(self):
              bc = c4d.BaseContainer()
              bc.SetBool(c4d.BITMAPBUTTON_BUTTON, True)
              bc.SetInt32(c4d.BITMAPBUTTON_ICONID1, c4d.Ocube)
              bc.SetInt32(c4d.BITMAPBUTTON_FORCE_SIZE, 32)
              button = self.AddCustomGui(10003, c4d.CUSTOMGUI_BITMAPBUTTON, "but", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 40, 40, bc)
              button.SetCommandDragId(c4d.Ocube)
              return True
      
          def Message(self, msg, result):
              if msg.GetId() == c4d.BFM_INTERACTEND:
                  if self.IsActive(10003):
                      print 'Icon clicked in the GeDialog.'
      

      Is it simply not possible to support older C4D-Versions AND have a draggable BitmapButton...?

      Thanks,
      Lasse

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

        Hi @lasselauch, I will take a look, but only in few days since R18 is the minimal version working for IsActive and it's more than 3years old, while we provide support only for 2 previous release.

        But maybe there is another way to catch this kind of stuff that would work in older version so that's why I said I will take a look.

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • lasselauchL
          lasselauch
          last edited by

          Thanks @m_adam,

          for now I've added a workaround for older versions so it's not possible to drag the buttons to the layout.

          Works for me, but would be nice to know anyway.

          Thanks,
          Lasse

          1 Reply Last reply Reply Quote 0
          • lasselauchL
            lasselauch
            last edited by

            Hi Maxime,

            I still have some problems using IsActive(). I'm having some c4d.plugins.CommandData utilizing the c4d.gui.ShowPopupDialog. Sadly sometimes the Popup will be called even after pressing the button. Happens escpially in the end of the following *.gif. (After clicking on the button, I constantly click on the Menubar, and sometimes the popup will be displayed again...)

            2020-04-07_09-36-59.gif

            My Message(self, msg, result) looks like the following:

                def Message(self, msg, result):
                    if c4d.GetC4DVersion() >= 18000:
                        #Handle CommandDragID
                        if msg.GetId() == c4d.BFM_INTERACTEND:
                            if self.IsActive(ids.IDC_BUTTON1):
                                c4d.CallCommand(ids.PLUGIN_ID_EXPORT)
            
                            elif self.IsActive(ids.IDC_BUTTON2):
                                c4d.CallCommand(ids.PLUGIN_ID_OMCLEANER)
            
                            elif self.IsActive(ids.IDC_BUTTON3):
                                c4d.CallCommand(ids.PLUGIN_ID_PYSCRIPTS)
            
                            elif self.IsActive(ids.IDC_BUTTON4):
                                c4d.CallCommand(ids.PLUGIN_ID_RECENTFILES)
                            
                            elif self.IsActive(ids.IDC_BUTTON5):
                                c4d.CallCommand(ids.PLUGIN_ID_CHATLOG)
            
                    return c4d.gui.GeDialog.Message(self, msg, result)
            

            Any ideas how to avoid or counter-act this!?

            Thanks,
            Lasse

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

              May I ask in what range you enumerated your Dialog controls?
              If I recall correctly, there was this kind of behavior if the control IDs were below a certain number.

              1 Reply Last reply Reply Quote 0
              • lasselauchL
                lasselauch
                last edited by

                The ids are starting from 20001.

                IDD_DIALOG = 20001
                IDC_BUTTONFLUSHGROUP = 20002
                IDC_BUTTON1 = 20003
                IDC_BUTTON2 = 20004
                IDC_BUTTON3 = 20005
                IDC_BUTTON4 = 20006
                IDC_BUTTON5 = 20007
                

                Then of course the Commands like ids.PLUGIN_ID_EXPORT are generated PluginIDs.

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

                  After looking at your GIF again, it seems like the following happens:
                  When checking for BFM_INTERACTEND and poking yround inyour dialog, the focus switches back to the last active Gadget. Thus your commands are fired since you are checking if the gadgets do have the focus.

                  1 Reply Last reply Reply Quote 0
                  • lasselauchL
                    lasselauch
                    last edited by

                    Yeah, I guess that makes sense.
                    What would be the best way to work around that behaviour?

                    Shall I return return c4d.gui.GeDialog.Message(self, msg, result) after each c4d.CallCommand()?

                    A simple else statement didn't work.

                    Cheers,
                    Lasse

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

                      This does not solve your initial issue since it requires the use of GetItemDim and it was introduced in R18 but here is how to avoid your second issue:

                      import c4d
                      
                      class Dialog(c4d.gui.GeDialog):
                          
                          def CreateLayout(self):
                              bc = c4d.BaseContainer()
                              bc.SetBool(c4d.BITMAPBUTTON_BUTTON, True)
                              bc.SetInt32(c4d.BITMAPBUTTON_ICONID1, c4d.Ocube)
                              bc.SetInt32(c4d.BITMAPBUTTON_FORCE_SIZE, 32)
                              button = self.AddCustomGui(10003, c4d.CUSTOMGUI_BITMAPBUTTON, "but", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 40, 40, bc)
                              button.SetCommandDragId(c4d.Ocube)
                              self.AddStaticText(10001, 0, 0, name="test")
                              return True
                      
                          def IsPositionOnGadget(self, gadgetId, x, y):
                              # Be sure that the windows is opened,
                              # in our case since we call it in BFM_INTERACTSTART it's ok
                              buttonData = self.GetItemDim(gadgetId)
                              
                              if not buttonData["x"] < x < buttonData["x"] + buttonData["w"]:
                                  return False
                      
                              if not buttonData["y"] < y < buttonData["y"] + buttonData["h"]:
                                  return False
                      
                              return True
                      
                          def Message(self, msg, result):
                              # Main thread
                              if msg.GetId() == c4d.BFM_INTERACTSTART:
                                  c4d.StopAllThreads()
                      
                                  # Check the mouse is clicked
                                  state = c4d.BaseContainer()
                                  self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSERIGHT, state)
                      
                                  if state.GetInt32(c4d.BFM_INPUT_CHANNEL) != 0:
                      
                                      # Get coordinates
                                      x = state.GetInt32(c4d.BFM_INPUT_X)
                                      y = state.GetInt32(c4d.BFM_INPUT_Y)
                                      g2l  = self.Global2Local() 
                                      x += g2l['x']  
                                      y += g2l['y']
                      
                                      # Checks the coordinate is within the range of the BitmapButton
                                      if self.IsPositionOnGadget(10003, x, y):
                                          print 'Icon clicked in the GeDialog.'
                      
                                          # Stop others event to be processed
                                          self.KillEvents()
                                          return True
                                      
                              return c4d.gui.GeDialog.Message(self, msg, result)
                      
                      # Main function
                      def main():
                          global dlg
                          dlg = Dialog()
                          dlg.Open(c4d.DLG_TYPE_ASYNC)
                      
                      # Execute main()
                      if __name__=='__main__':
                          main()
                      

                      Note that there is a very similar problem Disable default Right-Click Menu that you may found interesting about how to handle popup in your dialog.

                      And adding this constraint in mind, I'm afraid I don't see any solution to make it work before R18.
                      Cheers,
                      Maxime.

                      MAXON SDK Specialist

                      Development Blog, MAXON Registered Developer

                      1 Reply Last reply Reply Quote 0
                      • lasselauchL
                        lasselauch
                        last edited by

                        Thanks @m_adam for the insights!

                        Works like a charm!!

                        Cheers,
                        Lasse

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post