[SOLVED]SubDialog Redraw layout && color text



  • On 31/03/2017 at 16:56, xxxxxxxx wrote:

    I have a Gedialog Master class. And Another Gedialog class.
    When I press a button into the GeDialogMaster class I open my another Gedialog class.

    Then after something into the subDialog I want to update the ui of the SubDialog. But that didn't work. Flush seem to work but not the redraw part.

    I also got another little issue which is not related to SubDialog.
    I have a text with a color but if I select this text with right click, after the hoover the color recome by default.

    Here you get an exemple of what I'm speaking. Actually into my plugin I call dialog inAsync mode but for the exemple I guess it's more easy to run it into the Script Manager so I switched to Modal.

    import c4d
      
    class mainDialog(c4d.gui.GeDialog) :
        def __init__(self) :
            self.subDlg = MyOtherDialog()
      
        def CreateLayout(self) :
            self.AddButton(1001, c4d.BFH_CENTER, 60, 15, "Open")
            return True
      
        def Command(self, id, msg) :
            if id == 1001:
                self.subDlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=150, xpos=-1, ypos=-1)
            return True
      
    class MyOtherDialog(c4d.gui.GeDialog) :
        data = "aaaaa"
        def CreateLayout(self) :
            self.__create_ui()
            return True
      
        def __create_ui(self, refresh=False) :
            if refresh:
                self.LayoutFlushGroup(1002)
            else:
                self.GroupBegin(1002, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1, 1, "My Group")
                self.AddStaticText(1003, c4d.BFH_CENTER | c4d.BFV_SCALEFIT, name="test")
                if refresh:
                    self.SetString(1003, self.data)
                    self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(0.631, 1, 0.33))
                else:
                    self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(0.78, 0.257, 0.257))
      
                self.AddButton(1004, c4d.BFH_CENTER, 60, 15, "Refresh")
            self.GroupEnd()
      
            if refresh:
                self.LayoutChanged(1002)
      
        def Command(self, id, msg) :
            if id == 1004:
                self.__create_ui(True)
            
            return True
                
                
    def main() :
        main_dlg = mainDialog()
        main_dlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=150, xpos=-1, ypos=-1)
      
    if __name__=='__main__':
        main()
    

    Thanks in advance :)



  • On 01/04/2017 at 08:48, xxxxxxxx wrote:

    Hi,
    Your custom function that makes the controls is called by the CreateLayout() function.
    So you need to need to call the CreateLayout() function to reset the dialog controls.

    I couldn't find a "This gizmo is focused/not focused " option in the SDK. So I hacked together a work around using the Message() method.
    This way the text color automatically gets reset when the user is not RMB clicking on it. And is LMB clicking in the dialog.
    That way the other gizmos won't get reset. And user won't need to constantly push the reset button.

    NOTE:
    If there is a way to get the focused GeDialog gizmo with the SDK I'd like to know where it is.
    Because I could not find one.

    import c4d  
    from c4d import gui  
      
    class mainDialog(c4d.gui.GeDialog) :  
      def __init__(self) :  
          self.subDlg = MyOtherDialog()  
      
      def CreateLayout(self) :  
          self.AddButton(1001, c4d.BFH_CENTER, 60, 15, "Open")  
          return True  
      
      def Command(self, id, msg) :  
          if id == 1001:  
              self.subDlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=150, xpos=-1, ypos=-1)  
          return True  
      
    class MyOtherDialog(c4d.gui.GeDialog) :  
      data = "aaaaa"  
      def CreateLayout(self) :  
          self.__create_ui()  
          return True  
      
      def __create_ui(self, refresh=False) :  
      
          self.GroupBegin(1002, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1, 1, "My Group")  
          self.AddStaticText(1003, c4d.BFH_CENTER | c4d.BFV_SCALEFIT, name="test")  
          self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(1.0, 0, 0))  
          self.AddButton(1004, c4d.BFH_CENTER, 60, 15, "Refresh")  
          self.GroupEnd()   
      
      def Command(self, id, msg) :  
          if id == 1004:  
              self.CreateLayout()  #<---This should reset the entire dialog  
            
          return True  
        
      def Message(self, msg, result) :  
            
          #This will reset the text color back to red when the user LMB clicks in the dialog         
          if msg.GetId() == c4d.BFM_INPUT:  
              if msg.GetLong(c4d.BFM_INPUT_DEVICE) == c4d.BFM_INPUT_MOUSE:                  
                  if msg.GetLong(c4d.BFM_INPUT_CHANNEL) != c4d.BFM_INPUT_MOUSERIGHT:   
                      self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(1.0, 0, 0))   
      
          return gui.GeDialog.Message(self, msg, result)                  
                
    def main() :  
      main_dlg = mainDialog()  
      main_dlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=150, xpos=-1, ypos=-1)  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 01/04/2017 at 09:03, xxxxxxxx wrote:

    Thanks ScottA
    I didn't know we can mannually call the CreateLayout.
    But is it a limiation of the FlusshLayout / LayoutChanged?

    Because normally it should work.

    Is not the case but imagine I only want to update a group with custom data. The only way to do it it's set bool class member for checking if It's in refresh state. And then in CreateLayout do a conditional check based on this variable? It's a bit boring but it's ok

    Thanks for the workaround I finally did the same things but would love to know as you if there is a better way for doing this stuff.

    Anyway thanks you !



  • On 01/04/2017 at 10:00, xxxxxxxx wrote:

    The LayoutFlushGroup() function deletes the targeted group.
    So if you want it to come back after it's been deleted. You will need to rebuild it again from scratch.
    This can be done by calling the CreateLayout() method. Which will reset(rebuild) everything in the dialog.
    Or
    You can write a custom function that flushes the group, then re-builds the specific group and child gizmos when your button is pressed. Which the most common way I've seen people handle this.

    You might be able to do some simple re-setting tasks by giving your gizmos default values in the Init() method. And then calling Init() and using self.LayoutChanged(your group ID) in your button code.
    But I typically make a custom function whenever I need to change/reset only specific gizmos.

    -ScottA



  • On 01/04/2017 at 10:13, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    The LayoutFlushGroup() function deletes the targeted group.
    So if you want it to come back after it's been deleted. You will need to rebuild it again from scratch.
    This can be done by calling the CreateLayout() method. Which will reset(rebuild) everything in the dialog.

    Dammmmmn it's that to code during 20h... You make stupid error... I hate myself... I usually do the thing I did but I mess up an indent wich of course lead to the creation part was only done when refresh is not set..

    Then my normal code should be

        def __create_ui(self, refresh=False) :
            if refresh:
                self.LayoutFlushGroup(1002)
            else:
                self.GroupBegin(1002, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1, 1, "My Group")
      
            self.AddStaticText(1003, c4d.BFH_CENTER | c4d.BFV_SCALEFIT, name="test")
            if refresh:
                self.SetString(1003, self.data)
                self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(0.631, 1, 0.33))
            else:
                self.SetDefaultColor(1003, c4d.COLOR_TEXT, c4d.Vector(0.78, 0.257, 0.257))
      
            self.AddButton(1004, c4d.BFH_CENTER, 60, 15, "Refresh")
            self.GroupEnd()
      
            if refresh:
                self.LayoutChanged(1002)
    

    Wich obviously work.



  • On 01/04/2017 at 11:36, xxxxxxxx wrote:

    LOL.
    I threw away your create_ui function because I thought you were asking about a different thing.
    Glad you found the problem.

    -ScottA



  • On 03/04/2017 at 04:55, xxxxxxxx wrote:

    Hi,

    since we know, that you, gr4ph0s, are learn ing C++, here's the link to the C++ GeDialog Gadgets example and especially its UpdateDialog() function. We think, it demonstrates most needed update mechanisms.



  • On 03/04/2017 at 05:25, xxxxxxxx wrote:

    Thanks you andreas. Maybe I should have edited my first post since we have figured what is going wrong for hte refresh part. (Wich was a stupid error from me... Even if re-read my code 50times)

    But I still got an issue regarding the color of a StaticText after a left click it's reset to c4d default color. Is there a way for removing this behavior?

    import c4d
      
    class mainDialog(c4d.gui.GeDialog) :
        def CreateLayout(self) :
            self.AddStaticText(1001, c4d.BFH_CENTER | c4d.BFV_SCALEFIT, name="Right click on me")
            self.SetDefaultColor(1001, c4d.COLOR_TEXT, c4d.Vector(0.78, 0.257, 0.257))
            
            return True
      
        def Command(self, id, msg) :
            if id == 1001:
                color = self.GetDefaultColor(1001, c4d.COLOR_TEXT)
                self.SetString(1001, self.GetString(1003))
                self.SetDefaultColor(1001, c4d.COLOR_TEXT, c4d.Vector(0.631, 1, 0.33))
            
            return True
                
    def main() :
        main_dlg = mainDialog()
        main_dlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=100, defaulth=50, xpos=-1, ypos=-1)
      
    if __name__=='__main__':
        main()
    


  • On 05/04/2017 at 10:39, xxxxxxxx wrote:

    I think, you are doing something here, nobody else did before... never tested, never running... I have some doubts, this can be fixed in a modal dialog (not implying it will be easier in a non-model one), as there are no command messages fired by a static text. In a non-modal dialog you could... well... fake it with a timer (imagine me shudder), but you really shouldn't use non-modal dialogs from a Script Manager script.



  • On 05/04/2017 at 11:17, xxxxxxxx wrote:

    Thanks Andreas. Yes in my plugin it's in async so it's ok.
    I would have prefer a message but I will got for the timer option.

    But I guess it may be considered as an issue?

    Anyway Thanks ! :)



  • On 06/04/2017 at 02:06, xxxxxxxx wrote:

    Hi,

    yep, it is considered an issue and I have reported it to our development. But I hope you don't mind, it's probably considered pretty low priority. Nothing crashes, the user will still be able to work and it's a pretty uncommon use-case. Not saying, it's not annoying in your case, I completely understand, but I'm sure you understand we have to prioritize in some ways...



  • On 06/04/2017 at 02:15, xxxxxxxx wrote:

    Yes, no problem I completly understand !

    Again thanks you for everythings.
    And congrats for your plugin at maxon labs.


Log in to reply