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

    Is that posible to create a dialog like this with python ?

    Cinema 4D SDK
    python windows s26 2023 2024
    2
    5
    763
    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.
    • gheyretG
      gheyret
      last edited by

      Hi Plugincafe

      I'm wondering to create a window dialog like Cinema 4D About Dialog.
      Rounded corner, without window frame, fade in fade out and transparency maybe ?
      is that poible to do that?
      Or is there any other way to highly customize the window?

      787b09bb-8ed5-48d4-8b24-e83f289c79ea-image.png

      www.boghma.com

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

        Hello @gheyret,

        Thank you for reaching out to us. In short what you want to do is mostly not possible, as the About dialog of Cinema 4D is highly customized.

        You can have a borderless dialog in Cinema 4D with DLG_TYPE_ASYNC_POPUPEDIT. Fading of gadgets is possible with BFM_FADE, but not on a dialog level for users. Rounded corners and transparencies are not possible at all.

        When you want a color other than the builtin background color of dialogs, you will need to cover the whole dialog with a GeUserArea canvas or bitmap. And even then a small border will be left, even in borderless mode. You will also have to implement a way to close the dialog without its title bar; this is usually done via the dialog focus state. Finally, it is also not possible to reimplement moving the dialog window, as you can neither get or set the position of the window handle. Find below a quick draft of how close you can get.

        If you really need something like this, I recommend using a third-party UI library like QT, tkInter, imGUI, and others.

        Cheers,
        Ferdinand

        Result:

        2575ef08-fe02-4e50-b442-947519e017ed-image.png

        Code:

        """Realizes a dialog with not border and a white background.
        """
        
        import c4d
        
        class CanvasArea(c4d.gui.GeUserArea):
            """Realizes a white background element with text on it.
            """
            # Default size of the gadget.
            DEFAULT_SIZE: tuple[int, int] = (50, 50) 
        
            # The drawing colors and the offset of the drawn text in relation to the origin.
            COLOR_BACKGROUND: c4d.Vector = c4d.Vector(1)
            COLOR_TEXT: c4d.Vector = c4d.Vector(.1)
            OFFSET_TEXT: tuple[int, int] = (5, 5)
        
            # Indicates a f block.
            NEW_BLOCK: int = -1
        
            def __init__(self) -> None:
                """Initializes the canvas area.
                """
                self._size: tuple[int, int] = CanvasArea.DEFAULT_SIZE
                self._value: str = ""
        
            def GetMinSize(self) -> tuple[int, int]:
                """Returns the minimum size of the canvas area.
                """
                return self._size
            
            def DrawMsg(self, x1: int, y1: int, x2: int, y2: int, msg: c4d.BaseContainer) -> None:
                """Draws the white background and text on it.
                """
                self.DrawSetPen(CanvasArea.COLOR_BACKGROUND)
                self.DrawSetTextCol(CanvasArea.COLOR_TEXT, CanvasArea.COLOR_BACKGROUND)
        
                self.DrawRectangle(x1, y1, x2, y2)
                self.DrawSetFont(c4d.FONT_STANDARD)
                self.DrawText(self._value, *CanvasArea.OFFSET_TEXT)
        
                return
        
            @property
            def Value(self) -> str:
                """Returns the current value of the instance.
                """
                return self._value
        
            @Value.setter
            def Value(self, value: str) -> None:
                """Sets the value of the instance.
                """
                self._value = str(value)
                self.Redraw()
                
        
        class MyDialog(c4d.gui.GeDialog):
            """Realizes a simple dialog that uses and #InputArea.
            """
            ID_GRP_MAIN: int = 1000 # The identifier for the main layout group in the dialog.
            ID_USR_CANVAS: int = 1001 # The identifier for an #CanvasArea field in the dialog.
        
            def __init__(self) -> None:
                """Initializes the dialog. 
                """ 
                self._canvas: CanvasArea = CanvasArea()
                self._canvas.Value = "Hello World"
        
            def CreateLayout(self) -> bool:
                """Adds the InputArea gadget to the dialog inside a main layout group.
                """
                self.SetTitle("Canvas Area Example")
                self.GroupBegin(MyDialog.ID_GRP_MAIN, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
                self.GroupBorderSpace(5, 5, 5, 5)
        
                self.AddUserArea(MyDialog.ID_USR_CANVAS, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
                self.AttachUserArea(self._canvas, MyDialog.ID_USR_CANVAS)
        
                self.GroupEnd()
                return True
            
            def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> int:
                """Called by Cinema 4D to convey events to the dialog.
                """
                # Close the dialog when it loses focus.
                if msg.GetId() == c4d.BFM_LOSTFOCUS:
                    self.Close()
                
                return super().Message(msg, result)
        
        
        if __name__ == "__main__":
            # Run the example dialog. It is not recommended to use async dialogs in Script Manager scripts
            # in a production environment. 
            dlg: MyDialog = MyDialog()
            dlg.Open(c4d.DLG_TYPE_ASYNC_POPUPEDIT, defaultw=300, default=200)
        

        MAXON SDK Specialist
        developers.maxon.net

        gheyretG 1 Reply Last reply Reply Quote 0
        • gheyretG
          gheyret @ferdinand
          last edited by

          Hi @ferdinand
          Thank you for your reply. In fact, I have thought of several different solutions, such as:

          1. Take a screenshot using third-party library like pillow or pywin32 and use it as the background in GeUserArea, and draw some UI element what i want.

          2. Just using pyside2 to draw the user interface.

          3. Make a tiny software and use socket library to interact with C4D.

          But the aforementioned methods, in my opinion, lack the convenience and safety offered by C4D's methods. Additionally, it is worth noting that the methods I mentioned above may have certain imperfection.

          In fact, a few years ago I was concerned about whether there is a relevant way to achieve the effect I want, and tried to import Pyside2 in C4D, but there will be a "DLL import failed" error, this problem has been bothering me for a long time, and I still do not know how to deal with this problem.

          I realized that some of the effects of the "About" dialog box in C4D were exactly what I was looking for, so I came back to the forum to ask for your help again.

          www.boghma.com

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

            Hey @gheyret,

            Make a tiny software and use socket library to interact with C4D.

            If I understand you correctly here, then yes, this is probably the best way. You have basically two ways to integrate another GUI library into Cinema 4D.

            1. Install the library in one of the paths where you can install external libs in Cinema 4D, c4dpy, etc. The problem with this is that the Python VM of Cinema 4D is very similar to CPython, i.e., the standard Python, but not identical. And GUI libraries tend to be very specific about the environments they run in. We do not support third party GUI libraries in c4d for multiple reasons (tkinter is not part of our Python for exmple). We primarily want to enforce a uniform UI but the technical difficulties that come with using them is also one.
            2. Run the foreign GUI in a standard CPython instance of your choice or whatever the GUI lib considers to be its native environment. Then use sockets to communicate between Cinema and that external app. The subject has once been discussed here with some code examples being provided.

            I would recommend using the second pattern, as it is more secure. Because the first pattern might run fine on one machine (your development machine for example) and then miserably fail on another one.

            As a personal note: I would recommend not losing yourself too much in creating the most elaborate UIs. I know that you are going for a very polished look with the tools you publish in the plugin manager with Dunhou and jackadux, but sometimes UI stuff can be very time consuming for only looking a tiny bit better.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            gheyretG 1 Reply Last reply Reply Quote 0
            • gheyretG
              gheyret @ferdinand
              last edited by

              @ferdinand
              Indeed, the allure of good looks can be captivating at times. In fact, my primary objective was to explore the development of a pie toolbar, which may seem unconventional but has always held a deep fascination for me. I sincerely appreciate your valuable advice and will certainly give it a try.

              Cheers,
              Gheyret

              www.boghma.com

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