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

    how to Scroll UserArea

    Cinema 4D SDK
    s22 python
    2
    7
    1.4k
    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.
    • chuanzhenC
      chuanzhen
      last edited by

      Hi,
      In my scrollgroup, I created a UserArea to draw pictures, but the size of the pictures to be drawn is dynamic,
      that is to say, when the dialog is opened, different pictures are loaded and switching displayed by clicking button . When image size changing, expect the scrolling gui component to always be correct.
      (The picture drawn in the UserArea is 1:1, such as a 1280 * 720 picture file, the size in UserArea drawed also 1280 * 720).

      When I created it, the size of the UserArea could not automatically adapt to the image size, which caused the gui component of the scroll group to not work as expected.

      未标题-1.png

      After reading these two posts(Scrolling in UA/Scaling a GeUserArea in a ScrollGroup), I still can't achieve this goal! Thanks for any help!

      相信我,可以的!

      1 Reply Last reply Reply Quote 0
      • chuanzhenC
        chuanzhen
        last edited by

        This is the sample code, I tried to dynamically create the element inside the group to achieve, the picture is not drawn completely as expected:

        import c4d
        import os
        import sys
        from c4d import gui,bitmaps,plugins,utils,modules,storage
        
        
        PLUGIN_ID = 10000000 #only for test
        
        
        
        GROUP_SCROLL = 1100
        USEEAREA_GROUP = 1102
        USERAREA = 1101
        
        ADD_BUTTON = 1200
        
        class PreViewArea(gui.GeUserArea):
            bmp = None
        
        
            def DrawMsg(self,x1, y1, x2, y2, msg):
                self.OffScreenOn()
                self.SetClippingRegion(x1, y1, x2, y2)
                BG_colorDict = self.GetColorRGB(c4d.COLOR_BG)
                BG_color = c4d.Vector(BG_colorDict['r'], BG_colorDict['g'], BG_colorDict['b']) / 255.0
                self.DrawSetPen(BG_color)
                self.DrawRectangle(x1, y1, x2, y2)
        
                if self.bmp:
                    width = self.bmp.GetBw()
                    height = self.bmp.GetBh()
                    self.DrawBitmap(self.bmp, 0, 0, width, height, 0, 0, width, height, c4d.BMP_NORMAL)
        
        def dynamic_Group(dialog,ua):
            dialog.LayoutFlushGroup(USEEAREA_GROUP)
        
            if ua.bmp:
                width = ua.bmp.GetBw()
                height = ua.bmp.GetBh()
            else:
                width,height = 0,0
            dialog.AddUserArea(USERAREA, c4d.BFH_SCALE | c4d.BFV_SCALE,width,height)
            dialog.AttachUserArea(ua, USERAREA)
            dialog.LayoutChanged(USEEAREA_GROUP)
        
        class S_Lib_Dialog(gui.GeDialog):
            ua = PreViewArea()
        
        
            def CreateLayout(self):
                self.SetTitle("test")
                self.ScrollGroupBegin(PLUGIN_ID, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, c4d.SCROLLGROUP_HORIZ | c4d.SCROLLGROUP_VERT)
                self.GroupBegin(USEEAREA_GROUP,c4d.BFH_LEFT | c4d.BFV_TOP,1,1)
                self.GroupBorder(c4d.BORDER_ACTIVE_1)
                self.AddUserArea(USERAREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
                self.AttachUserArea(self.ua, USERAREA)
                self.GroupEnd()
        
                self.GroupEnd()
                self.AddButton(ADD_BUTTON,c4d.BFH_SCALEFIT,150,30,"Load image")
        
        
                return True
        
            def Command(self, id, msg):
                if id == ADD_BUTTON:
                    path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES)
                    if path:
                        bmp = bitmaps.BaseBitmap()
                        result,ismovie = bmp.InitWith(path)
                        if result == c4d.IMAGERESULT_OK:
                            self.ua.bmp = bmp
                            dynamic_Group(self, self.ua)
                            self.ua.Redraw()
                        else:
                            print("Load image Fail")
                    else:
                        print("Not select image")
        
        
        
                    return True
        
                return True
        
        
        
        
        
        
        class S_Lib(plugins.CommandData):
        
            dialog = None
        
            def Execute(self,doc):
                # create the dialog
                if self.dialog is None:
                    self.dialog = S_Lib_Dialog()
        
                return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=800, defaulth=400)
        
            def RestoreLayout(self, sec_ref):
                # manage nonmodal dialog
                if self.dialog is None:
                    self.dialog = S_Lib_Dialog()
        
                return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
        
        
        # Execute main()
        if __name__=='__main__':
            path, fn = os.path.split(__file__)
            plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                          str="test",
                                          info=0,
                                          help="",
                                          dat=S_Lib(),
                                          icon=None)
        
        

        相信我,可以的!

        1 Reply Last reply Reply Quote 1
        • M
          m_adam
          last edited by

          Hi @chuanzhen just to let you know I'm a bit busy with the release but I will look into it today or tomorrow. Thanks a lot for your code-sample this help a lot.

          Cheers,
          Maxime.

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          chuanzhenC 1 Reply Last reply Reply Quote 0
          • chuanzhenC
            chuanzhen @m_adam
            last edited by

            @m_adam Thanks!

            相信我,可以的!

            1 Reply Last reply Reply Quote 0
            • M
              m_adam
              last edited by m_adam

              Hi @chuanzhen just to let know I was able to reproduce your issue, but still not able to find a correct workaround with the time I had today, I will have a deeper look at it Monday and this will be my top priority 🙂

              Cheers,
              Maxime.

              MAXON SDK Specialist

              Development Blog, MAXON Registered Developer

              1 Reply Last reply Reply Quote 0
              • M
                m_adam
                last edited by m_adam

                Hi @chuanzhen you have to override the GetMinSize in order to notify the Dialog about the size of your GeUserArea, the issue I had is that I overlooked to update the value within your dynamic_Group method so it was not working properly.

                So here you adopted code that works properly

                import c4d
                import os
                import sys
                from c4d import gui, bitmaps, plugins, utils, modules, storage
                
                PLUGIN_ID = 10000000  # only for test
                
                GROUP_SCROLL = 1100
                USEEAREA_GROUP = 1102
                USERAREA = 1101
                
                ADD_BUTTON = 1200
                
                
                class PreViewArea(gui.GeUserArea):
                
                    def __init__(self):
                        self.bmp = None
                        self.width = 0
                        self.height = 0
                
                    def DrawMsg(self, x1, y1, x2, y2, msg):
                        self.OffScreenOn()
                        self.SetClippingRegion(x1, y1, x2, y2)
                        BG_colorDict = self.GetColorRGB(c4d.COLOR_BG)
                        BG_color = c4d.Vector(BG_colorDict['r'], BG_colorDict['g'], BG_colorDict['b']) / 255.0
                        self.DrawSetPen(BG_color)
                        self.DrawRectangle(x1, y1, x2, y2)
                
                        if self.bmp:
                            self.width = self.bmp.GetBw()
                            self.height = self.bmp.GetBh()
                            self.DrawBitmap(self.bmp, 0, 0, self.width, self.height, 0, 0, self.width, self.height, c4d.BMP_NORMAL)
                
                    def GetMinSize(self):
                        return self.width, self.height
                
                
                def dynamic_Group(dialog, ua):
                    dialog.LayoutFlushGroup(USEEAREA_GROUP)
                
                    if ua.bmp:
                        ua.width = ua.bmp.GetBw()
                        ua.height = ua.bmp.GetBh()
                    else:
                        ua.width, ua.height = 0, 0
                
                    dialog.AddUserArea(USERAREA, c4d.BFH_SCALE | c4d.BFV_SCALE, ua.width, ua.height)
                    dialog.AttachUserArea(ua, USERAREA)
                    dialog.LayoutChanged(USEEAREA_GROUP)
                
                
                class S_Lib_Dialog(gui.GeDialog):
                
                    def __init__(self):
                        self.ua = PreViewArea()
                
                    def CreateLayout(self):
                        self.SetTitle("test")
                        self.ScrollGroupBegin(PLUGIN_ID, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, c4d.SCROLLGROUP_HORIZ | c4d.SCROLLGROUP_VERT)
                        self.GroupBegin(USEEAREA_GROUP, c4d.BFH_LEFT | c4d.BFV_TOP, 0, 0)
                        self.GroupBorder(c4d.BORDER_ACTIVE_1)
                        self.AddUserArea(USERAREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
                        self.AttachUserArea(self.ua, USERAREA)
                        self.GroupEnd()
                
                        self.GroupEnd()
                        self.AddButton(ADD_BUTTON, c4d.BFH_SCALEFIT, 150, 30, "Load image")
                
                        return True
                
                    def Command(self, id, msg):
                        if id == ADD_BUTTON:
                            path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES)
                            if path:
                                bmp = bitmaps.BaseBitmap()
                                result, ismovie = bmp.InitWith(path)
                                if result == c4d.IMAGERESULT_OK:
                                    self.ua.bmp = bmp
                                    dynamic_Group(self, self.ua)
                                    self.ua.Redraw()
                                else:
                                    print("Load image Fail")
                            else:
                                print("Not select image")
                
                            return True
                
                        return True
                
                
                class S_Lib(plugins.CommandData):
                    dialog = None
                
                    def Execute(self, doc):
                        # create the dialog
                        if self.dialog is None:
                            self.dialog = S_Lib_Dialog()
                
                        return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=800, defaulth=400)
                
                    def RestoreLayout(self, sec_ref):
                        # manage nonmodal dialog
                        if self.dialog is None:
                            self.dialog = S_Lib_Dialog()
                
                        return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
                
                
                # Execute main()
                if __name__ == '__main__':
                    path, fn = os.path.split(__file__)
                    plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                                  str="test",
                                                  info=0,
                                                  help="",
                                                  dat=S_Lib(),
                                                  icon=None)
                

                As a side note I would advice you to use member variable bound to instance and not directly to the class itself.

                Cheers,
                Maxime.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                chuanzhenC 1 Reply Last reply Reply Quote 0
                • chuanzhenC
                  chuanzhen @m_adam
                  last edited by

                  @m_adam Thanks for your help,great work!

                  相信我,可以的!

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