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

    Getting rid of the burger icon in a dialog

    Cinema 4D SDK
    r25 c++
    2
    12
    1.6k
    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.
    • fwilleke80F
      fwilleke80
      last edited by fwilleke80

      Hi,

      I have a GeDialog, and I want it to behave like e.g. the preset popups in Gradient and Spline GUI do: Those dialogs have no menu bar, but they do have a title bar with a close button. And since they don't have the burger icon, they can't be docked into the layout. That's exactly what I want.

      I open the dialog using the flag DLG_TYPE::ASYNC_TOOLBAR, which is the closest to the above described behavior. However, the dialog still has the burger icon, and can also be docked into the layout. I don't want that, how can I get rid of it?

      Thanks in advance,
      Frank

      www.frankwilleke.de
      Only asking personal code questions here.

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @fwilleke80
        last edited by ferdinand

        Hey Frank,

        Thank you for reaching out to us. I am a bit confused as you seem to imply that you want an async dialog without the triple bar character ≡ as an icon. That is not possible, and in my opinion also not desirable, at least from an enforcing UX-guidelines standpoint. You can add the triple bar icon, Cinema 4D calls that thing "pin", with DIALOG_PIN, but you cannot remove it.

        Things like the gradient selection dialog are simply a modal dialog. They will always lack the pin. Dialogs also do not have menus unless you add them.

        aef3e31c-a70c-4197-904b-652fa90fd8eb-image.png

        What might be an additional source of confusion is that these modal asset selection dialogs all implement the "close when lost focus"-logic, which might make them feel "less modal". See the simple Python example at the end of my posting for details.

        Cheers,
        Ferdinand

        PS: Eh, now I see it too, the gradient dialog as the red tool dialog closing icon. Probably custom, I would say DLG_TYPE_MODAL_RESIZEABLE should do the trick, or am I overlooking something else?

        Result:
        df9d1d2e-3c1f-47ad-b123-4ed0dbc3a4a9-image.png

        Code:

        """Implements a dialog which behaves similar to the asset selection dialogs.
        """
        
        import c4d
        import random
        
        class TestDialog(c4d.gui.GeDialog):
            """
            """
            def CreateLayout(self) -> bool:
                """Called by Cinema 4D to populate the dialog with gadgets.
                """
                self.SetTitle("Test")
                for i in range(1000, 1011):
                    label: str = "".join(chr (random.randint(41, 90)) for _ in range(20))
                    self.AddStaticText(i, c4d.BFH_SCALE, name=label)
                return True
            
            def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> int:
                """Called by Cinema 4D to convey events to the dialog.
                """
                if msg.GetId() == c4d.BFM_LOSTFOCUS:
                    self.Close()
                
                return super().Message(msg, result)
        
        if __name__ == "__main__":
            dlg: TestDialog = TestDialog()
            dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, 0, 500, 500)
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • fwilleke80F
          fwilleke80
          last edited by

          Oh, then I might have made some other mistake.
          Will double check and try DLG_TYPE_MODAL_RESIZEABLE.

          Thank you!

          www.frankwilleke.de
          Only asking personal code questions here.

          1 Reply Last reply Reply Quote 0
          • fwilleke80F
            fwilleke80
            last edited by fwilleke80

            Checked, and you're abolutely right. DLG_TYPE::MODE_RESIZABLE is the correct choice. I don't know why I was convinced it had to be an asynchronous dialog.

            The closing on BFM_LOSTFOCUS I already put in 😉

            Even though my initial question has been anwered, maybe a follow-up on that: I also want the dialog to close when the ESC key is pressed (like the aforementioned C4D preset dialogs do, too). After consulting the docs, I thought it should work this way:

            Int32 MyDialog::Message(const BaseContainer& msg, BaseContainer& result)
            {
            	switch (msg.GetId())
            	{
            		// Close dialog when ESC is pressed
            		case BFM_INPUT:
            		{
            			const maxon::Int32 inputDevice = msg.GetInt32(BFM_INPUT_DEVICE);
            			const maxon::Int32 ascVal = msg.GetInt32(BFM_INPUT_ASC);
            			if (inputDevice == BFM_INPUT_KEYBOARD && ascVal == KEY_ESC)
            				Close();
            			break;
            		}
            	}
            
            	return SUPER::Message(msg, result);
            }
            

            However, BFM_INPUT is never received when pressing keys on the keyboard. Only mouse clicks trigger this message. How does that work? And what could be a possible reason for not receiving BFM_INPUT on keyboard events? There are several code examples here on the Café that indicate it should work.

            Cheers,
            Frank

            www.frankwilleke.de
            Only asking personal code questions here.

            ferdinandF 1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand @fwilleke80
              last edited by ferdinand

              Hey @fwilleke80,

              I know that I always say that, but that question is ambiguous 🙂 What is being broadcasted to a dialog, depends on the gadgets that are in the dialog, and which one is focused. In short, not everything receives the full input stream. But a dialog itself should receive all keyboard events.

              I also faintly remembered that the ESC key is handled separately in all the ancient GUI backend, hence the symbol BFM_ACTION_ESC. For the dialog from above, and this message method,

                  def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> int:
                      """Called by Cinema 4D to convey events to the dialog.
                      """
                      mid: int = msg.GetId()
                      if mid == c4d.BFM_LOSTFOCUS:
                          self.Close()
                      elif mid in (c4d.BFM_ACTION, c4d.BFM_INPUT):
                          symbol: str = "BFM_ACTION" if mid == c4d.BFM_ACTION else "BFM_INPUT"
                          print ("-" * 79)
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_VALUE] = }")
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_ESC] = }")
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_ID] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_VALUE] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_VALUE_REAL] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_ASC] = }")
                      return super().Message(msg, result)
              

              and pressing first ESC and then e, I got this output:

              -------------------------------------------------------------------------------
              BFM_ACTION: msg[c4d.BFM_ACTION_VALUE] = 1
              BFM_ACTION: msg[c4d.BFM_ACTION_ESC] = None
              BFM_ACTION: msg[c4d.BFM_ACTION_ID] = 2
              BFM_ACTION: msg[c4d.BFM_INPUT_VALUE] = None
              BFM_ACTION: msg[c4d.BFM_INPUT_VALUE_REAL] = None
              BFM_ACTION: msg[c4d.BFM_INPUT_ASC] = None
              -------------------------------------------------------------------------------
              BFM_INPUT: msg[c4d.BFM_ACTION_VALUE] = None
              BFM_INPUT: msg[c4d.BFM_ACTION_ESC] = None
              BFM_INPUT: msg[c4d.BFM_ACTION_ID] = None
              BFM_INPUT: msg[c4d.BFM_INPUT_VALUE] = 1
              BFM_INPUT: msg[c4d.BFM_INPUT_VALUE_REAL] = 1.0
              BFM_INPUT: msg[c4d.BFM_INPUT_ASC] = 'e'
              

              So, pressing ESC is an action and not an input event in a dialog (when the dialog itself is focused), because everything else would be too easy, right? However, nothing among the usual suspects conveys clearly that this is an ESC-button press event. Noteworthy is however the action ID 2, neither the dialog itself nor any of the gadgets has that ID, so it could be that it encodes that this is the ESC button being pressed while the dialog itself is in focus. But that is pure speculation.

              Hopefully, this gets you started. For a more concrete answer, I would have to start digging around in the GUI backend to see what is what. I currently do not have the time to do that, as we are quite busy now. When you are still stuck, please drop me a note here, and I will see if I can squeeze in some time next week.

              Thank you for your understanding,
              Ferdinand

              PS: There is nothing else in that message container when ESC is being pressed.

              167aa802-9a57-4e40-bb19-b751c2cc9911-image.png

              Full code:

              """Implements a dialog which behaves similar to the asset selection dialogs.
              """
              
              import c4d
              import random
              
              class TestDialog(c4d.gui.GeDialog):
                  """
                  """
                  def CreateLayout(self) -> bool:
                      """Called by Cinema 4D to populate the dialog with gadgets.
                      """
                      self.SetTitle("Test")
                      for i in range(1000, 1011):
                          label: str = "".join(chr (random.randint(41, 90)) for _ in range(20))
                          self.AddStaticText(i, c4d.BFH_SCALE, name=label)
                      return True
                  
                  def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> int:
                      """Called by Cinema 4D to convey events to the dialog.
                      """
                      mid: int = msg.GetId()
                      if mid == c4d.BFM_LOSTFOCUS:
                          self.Close()
                      elif mid in (c4d.BFM_ACTION, c4d.BFM_INPUT):
                          symbol: str = "BFM_ACTION" if mid == c4d.BFM_ACTION else "BFM_INPUT"
                          print ("-" * 79)
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_VALUE] = }")
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_ESC] = }")
                          print (f"{symbol}: {msg[c4d.BFM_ACTION_ID] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_VALUE] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_VALUE_REAL] = }")
                          print (f"{symbol}: {msg[c4d.BFM_INPUT_ASC] = }")
                      return super().Message(msg, result)
              
              if __name__ == "__main__":
                  dlg: TestDialog = TestDialog()
                  dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, 0, 500, 500)
              

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 0
              • fwilleke80F
                fwilleke80
                last edited by

                Ah, nice, thank you!
                Will definitely try BFM_ACTION_ESC!

                www.frankwilleke.de
                Only asking personal code questions here.

                1 Reply Last reply Reply Quote 0
                • fwilleke80F
                  fwilleke80
                  last edited by

                  Hi Ferdinand,

                  I can't get that BFM_ACTION_ESC to work...

                  Int32 MyDialog::Message(const BaseContainer& msg, BaseContainer& result)
                  {
                  	switch (msg.GetId())
                  	{
                  		// Close dialog when clicking anywhere outside of it
                  		case BFM_LOSTFOCUS:
                  		{
                  			Close();
                  			return true;
                  		}
                  
                  		// Close dialog when pressing ESC
                  		case BFM_ACTION:
                  		case BFM_INPUT:
                  		{
                  			if (msg.GetBool(BFM_ACTION_ESC))
                  			{
                  				Close();
                  				return true;
                  			}
                  			break;
                  		}
                  	}
                  
                  	return SUPER::Message(msg, result);
                  }
                  

                  Nothing happens when I press ESC. What am I doing wrong?

                  Cheers,
                  Frank

                  www.frankwilleke.de
                  Only asking personal code questions here.

                  ferdinandF 1 Reply Last reply Reply Quote 0
                  • ferdinandF
                    ferdinand @fwilleke80
                    last edited by ferdinand

                    Hello @fwilleke80,

                    well the answer lies partially in my answer above. Without wanting to be rude, I would recommend going back an reading my answer again. Also because I do not remember all details of this topic anymore myself, so I might have forgotten details too 🙂

                    The most important bit was this here:

                    @ferdinand said in Getting rid of the burger icon in a dialog:

                    and pressing first ESC and then e, I got this output:

                    -------------------------------------------------------------------------------
                    BFM_ACTION: msg[c4d.BFM_ACTION_VALUE] = 1
                    BFM_ACTION: msg[c4d.BFM_ACTION_ESC] = None
                    BFM_ACTION: msg[c4d.BFM_ACTION_ID] = 2
                    BFM_ACTION: msg[c4d.BFM_INPUT_VALUE] = None
                    BFM_ACTION: msg[c4d.BFM_INPUT_VALUE_REAL] = None
                    BFM_ACTION: msg[c4d.BFM_INPUT_ASC] = None
                    -------------------------------------------------------------------------------
                    BFM_INPUT: msg[c4d.BFM_ACTION_VALUE] = None
                    BFM_INPUT: msg[c4d.BFM_ACTION_ESC] = None
                    BFM_INPUT: msg[c4d.BFM_ACTION_ID] = None
                    BFM_INPUT: msg[c4d.BFM_INPUT_VALUE] = 1
                    BFM_INPUT: msg[c4d.BFM_INPUT_VALUE_REAL] = 1.0
                    BFM_INPUT: msg[c4d.BFM_INPUT_ASC] = 'e'
                    

                    So, pressing ESC is an action and not an input event in a dialog (when the dialog itself is focused), because everything else would be too easy, right? However, nothing among the usual suspects conveys clearly that this is an ESC-button press event. Noteworthy is however the action ID 2, neither the dialog itself nor any of the gadgets has that ID, so it could be that it encodes that this is the ESC button being pressed while the dialog itself is in focus. But that is pure speculation.

                    So, your code cannot work. The question to solve would be: What does the ID 2 mean? is this encoding just something like the dialog or implicit dialog group as a gadget, or does that communicate directly that ESC is being pressed? And how is the action value to be interpreted? When I remember correctly, it does not match any of the ESC key symbols.

                    I do not know and would have to start digging myself to find out. Fact is however, that the action value and id are the only thing which is emitted when you press ESC on a dialog. So, searching for other venues is meaningless (see my answer above).

                    It might be that detecting the ESC key being pressed is not possible in a super reliable way on a dialog level, and that you need a user area for that or must poll the key state yourself (which does not work either).

                    Cheers,
                    Ferdinand

                    MAXON SDK Specialist
                    developers.maxon.net

                    1 Reply Last reply Reply Quote 0
                    • fwilleke80F
                      fwilleke80
                      last edited by

                      Thanks, I'll keep digging 🙂

                      www.frankwilleke.de
                      Only asking personal code questions here.

                      ferdinandF 1 Reply Last reply Reply Quote 0
                      • ferdinandF
                        ferdinand @fwilleke80
                        last edited by ferdinand

                        Hey @fwilleke80,

                        I asked Pablo today about this and he told me that BFM_ACTION_ID == 2 conveys IDC_CANCEL which how the escape button being pressed is expressed.

                        Int32 MyDialog::Message(const BaseContainer& msg, BaseContainer& result)
                        {
                          // Catch the user pressing escape while the dialog is focused.
                          if ((msg.GetId() == BFM_ACTION) && (msg.GetBool(BFM_ACTION_ID) == IDC_CANCEL))
                            // ...
                        

                        Stuff is not documented at all and these symbols are also used for ok/cancel button group press events. I will update the docs a little bit in this regard.

                        Closing this thread now, cheers,
                        Ferdinand

                        MAXON SDK Specialist
                        developers.maxon.net

                        1 Reply Last reply Reply Quote 0
                        • fwilleke80F
                          fwilleke80
                          last edited by

                          Wow, thanks! 🙂

                          www.frankwilleke.de
                          Only asking personal code questions here.

                          1 Reply Last reply Reply Quote 0
                          • fwilleke80F
                            fwilleke80
                            last edited by

                            Woot, it works! 🕺

                            www.frankwilleke.de
                            Only asking personal code questions here.

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