Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    Dialogs and InputsStates

    Scheduled Pinned Locked Moved PYTHON Development
    4 Posts 0 Posters 556 Views
    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.
    • H Offline
      Helper
      last edited by

      On 24/05/2017 at 23:32, xxxxxxxx wrote:

      Hello!

      I'm learning about dialogs and inputs states. I'm looking into it, but there are some things I don't fully understand. In this case I want to make a basic dialog that return one string information with one "OK" button and "Cancel" button. I already wrote the code and works correctly but I don't understand the correct way to assign inputs commands to "OK" (Enter Key) and "Cancel" (esc Key).

      But, If I execute a basic input states without dialogs works great. When I assign this inputs states the dialog stop working, doesn't recognize the OK and Cancel actions.

      Can someone help me to understand what is happening?

      Here is the code with one input state for the OK button:

      import c4d
      from c4d import gui
       
      LBL_INFO = 1000
      NAME = 10001
      GROUP_OPTIONS = 20000
      BTN_OK = 20001
      BTN_CANCEL = 20002

      class OptionsDialog(gui.GeDialog) :
        def CreateLayout(self) :
          self.SetTitle('Title')
          self.AddStaticText(LBL_INFO, c4d.BFH_LEFT, name='String Name:') 
          self.AddEditText(NAME, c4d.BFH_SCALEFIT)
          self.SetString(NAME, 'Default Name') 
          # Buttons
          self.GroupBegin(GROUP_OPTIONS, c4d.BFH_CENTER, 2, 1)
          self.AddButton(BTN_OK, c4d.BFH_SCALE, name='OK')
          self.AddButton(BTN_CANCEL, c4d.BFH_SCALE, name='Cancel')
          self.GroupEnd()
          self.ok = False
          return True
       
        # Action Buttons Inputs
        def Command(self, id, msg) :
          bc = c4d.BaseContainer()
          
          if c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD,c4d.KEY_ENTER,bc) :
              if bc[c4d.BFM_INPUT_VALUE]==1:
                 if id==BTN_CANCEL:
                    self.Close()
          elif id==BTN_OK:
            self.ok = True
            self.option_find_string = self.GetString(NAME)
            self.Close()
          return True

      def dialog_test() :
          dlg = OptionsDialog()
          dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50)
          if not dlg.ok:
            return
          print "1"+dlg.option_find_string

      if __name__=='__main__':
          dialog_test()

      ---------------------------------------

      Thanks for the help, cheers!

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 25/05/2017 at 03:13, xxxxxxxx wrote:

        Hi,

        If you want only Ok and Cancel buttons plus associated Enter/Escape keys detection, GetInputState() is not needed as there are already default input commands for these.

        A dialog sends Enter/Escape keys events to GeDialog.Command() with the IDC_OK (value 1) and IDC_CANCEL (value 2) IDs.
        Also Ok/Cancel buttons can be added with GeDialog.AddDlgGroup() passing c4d.DLG_OK|c4d.DLG_CANCEL.
        Then the same IDs are sent for the keys and buttons events to GeDialog.Command().

        Here's how to use IDC_OK/IDC_CANCEL IDs and GeDialog.AddDlgGroup() in your OptionsDialog :

        class OptionsDialog(gui.GeDialog) :
          
            IDC_LABELNAME = 1000
            IDC_EDITNAME = 1001
          
            def CreateLayout(self) :
          
                self.SetTitle('Enter Name')
          
                self.AddStaticText(self.IDC_LABELNAME, c4d.BFH_LEFT, name='String Name:') 
                self.AddEditText(self.IDC_EDITNAME, c4d.BFH_SCALEFIT)
                self.SetString(self.IDC_EDITNAME, 'Default Name')
          
                # Ok/Cancel buttons
          
                self.AddDlgGroup(c4d.DLG_OK|c4d.DLG_CANCEL)
          
                self.ok = False
          
                return True
          
            def Command(self, id, msg) :
          
                if id == c4d.IDC_OK:
                    self.ok = True
                    self.findName = self.GetString(self.IDC_EDITNAME)
                    self.Close()
                elif id == c4d.IDC_CANCEL:
                    self.Close()
          
                return True
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 25/05/2017 at 23:02, xxxxxxxx wrote:

          Thanks Yannick! This is great and useful. 🙂

          And how can I center my dialog on my screen? I've tried to set xpos and ypos with a c4d.BFH_CENTER and c4d.BFV_CENTER flags but returns in 0. This flags are only for dialogs buttons and XYpos can it only be int?.

          Thanks!

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 26/05/2017 at 03:21, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            And how can I center my dialog on my screen? I've tried to set xpos and ypos with a c4d.BFH_CENTER and c4d.BFV_CENTER flags but returns in 0. This flags are only for dialogs buttons and XYpos can it only be int?.

            BFH_CENTER and BFV_CENTER are also integer and their value is zero. These flags are only valid for layout flags of dialog gadgets. xpos and ypos need coordinates.

            To center a dialog on the screen, you have to calculate the center position. The following function uses GeGetScreenDimensions() and returns the screen center:

            def GetScreenCenter() :
                # Get mouse input state
                state = c4d.BaseContainer()
                ret = gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, state)
                if not ret:
                    return (0, 0)
              
                # Retrieve mouse X and Y coordinates
                x = state[c4d.BFM_INPUT_X]
                y = state[c4d.BFM_INPUT_Y]
              
                # Get whole screen dimensions
                xmin, ymin, xmax, ymax = gui.GeGetScreenDimensions(x, y, True).values()
              
                # Calculate screen center
                xcenter = xmin + (xmax - xmin) / 2
                ycenter = ymin + (ymax - ymin) / 2
              
                return (xcenter, ycenter)
            

            Then just subtracts half the size of the dialog width and height to open the dialog at the very center of the screen.

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