Dialogs and InputsStates



  • 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!



  • 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
    


  • 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!



  • 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.


Log in to reply