how to Scroll UserArea
-
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.
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!
-
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)
-
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. -
@m_adam Thanks!
-
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. -
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. -
@m_adam Thanks for your help,great work!