Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hello, I'm trying to resize a GeUserArea within a ScrollGroup with a gui Slider. The GeUserArea's border is not being redrawn properly in my script as I don't think I'm calling the Redraw() / LayoutChanged() in the correct way: it's drawing unwanted lines as I drag the slider and scrollbar.
Redraw()
LayoutChanged()
I just want one solid border. The extra borders go away upon release of the Slider handle but are persistent with the scrollbar. Where would be the right place to call Redraw (or is something else causing the problem)? Thank you!
import c4d from c4d import gui class ExampleUserArea(c4d.gui.GeUserArea): def __init__(self, x, y, width, height): super(ExampleUserArea, self).__init__() self.x = x self.y = y self.width = width self.height = height self.Redraw() def DrawMsg(self, x1, y1, x2, y2, msg) : self.OffScreenOn() self.SetClippingRegion(x1, y1, x2, y2) self.DrawRectangle(x1, y1, x2, y2) self.DrawBorder(c4d.BORDER_IN, x1, y1, x2, y2) def GetMinSize(self): return self.width, self.height def InputEvent(self, msg) : self.Redraw() return True class ExampleDialog(c4d.gui.GeDialog): ID_SLIDER = 10000 ID_UA = 10001 ID_SCROLLGRP = 10002 def __init__(self): pass def Command(self, id, data): if id == self.ID_SLIDER: self.ua.height = int(self.GetFloat(self.ID_SLIDER)) print(self.ua.width,self.ua.height) self.ua.LayoutChanged() return True def CreateLayout(self): self.SetTitle("Scrolling UserArea Example") self.AddSlider(self.ID_SLIDER, c4d.BFH_SCALEFIT | c4d.BFV_BOTTOM, 10) self.SetFloat(self.ID_SLIDER, 200, 1, 1000, 1) if self.ScrollGroupBegin(self.ID_SCROLLGRP, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, scrollflags=c4d.SCROLLGROUP_VERT): self.ua = ExampleUserArea(0,0,200,200) self.AddUserArea(self.ID_UA, c4d.BFH_LEFT | c4d.BFV_TOP) self.AttachUserArea(self.ua, self.ID_UA) self.GroupEnd() self.ua.Redraw() return True def main(): dlg = ExampleDialog() dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, xpos=-2, ypos=-2, defaultw=400, defaulth=400) if __name__=='__main__': main()
Hi @blastframe just as a temporary workaround (since I confirm there is a bug in our side also).
Here a solution that cancels the initials DrawMsg and replaces with a custom one (with the correct Size). This way everything is working as expected (but keep in mind this is a hack, but I see only this solution as a workaround).
import c4d import os from c4d import gui class ExampleUserArea(c4d.gui.GeUserArea): def __init__(self, x, y): super(ExampleUserArea, self).__init__() # Init the bitmap fn = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) image = "random_img.jpg" path = os.path.join(fn,image) self.bmp = c4d.bitmaps.BaseBitmap() if self.bmp.InitWith(path)[0] != c4d.IMAGERESULT_OK: raise ValueError("Cannot load image " + path + ".") # During the init, set the width and height by the size of the Bitmap self.width, self.height = self.bmp.GetSize() def DrawMsg(self, x1, y1, x2, y2, msg): self.OffScreenOn() self.SetClippingRegion(x1, y1, x2, y2) self.DrawBitmap(self.bmp, x1, y1, x2, y2, 0, 0, self.bmp.GetBw(), self.bmp.GetBh(), c4d.BMP_NORMAL | c4d.BMP_ALLOWALPHA) self.DrawBorder(c4d.BORDER_IN, x1, y1, x2, y2) def GetMinSize(self): return self.width, self.height def Message(self, msg, result): # Catch the draw message to cancel it (return True) # and call ourself the DrawMsg with the dimension we expect if msg.GetId() == c4d.BFM_DRAW: self.DrawMsg(0, 0, self.width, self.height, c4d.BaseContainer()) return True return c4d.gui.GeUserArea.Message(self, msg, result) def InputEvent(self, msg) : self.Redraw() return True class ExampleDialog(c4d.gui.GeDialog): ID_SLIDER = 10000 ID_UA = 10001 ID_SCROLLGRP = 10002 def __init__(self): pass def Command(self, id, data): if id == self.ID_SLIDER: self.ua.height = int(self.GetFloat(self.ID_SLIDER)) self.ua.LayoutChanged() self.LayoutChanged(self.ID_SCROLLGRP) return True def CreateLayout(self): self.SetTitle("Scrolling UserArea Example") self.AddSlider(self.ID_SLIDER, c4d.BFH_SCALEFIT | c4d.BFV_BOTTOM, 10) self.SetFloat(self.ID_SLIDER, 200, 1, 1000, 1) if self.ScrollGroupBegin(self.ID_SCROLLGRP, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, scrollflags=c4d.SCROLLGROUP_VERT): self.ua = ExampleUserArea(0, 0) self.AddUserArea(self.ID_UA, c4d.BFH_LEFT | c4d.BFV_TOP) self.AttachUserArea(self.ua, self.ID_UA) self.GroupEnd() return True def main(): global dlg dlg = ExampleDialog() dlg.Open(c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, defaultw=400, defaulth=400) if __name__=='__main__': main()
Cheers, Maxime.
Hey @blastframe quickly looking at your code, you redraw the GeUserArea but not the whole group.
def Command(self, id, data): if id == self.ID_SLIDER: self.ua.height = int(self.GetFloat(self.ID_SLIDER)) print(self.ua.width,self.ua.height) self.ua.LayoutChanged() self.LayoutChanged(self.ID_SCROLLGRP) return True
Cheers, Maxime
@m_adam Thanks for the reply, Maxime! That fixed the issue with the slider, however the issue remains when the group is scrolled. I tried this in the Command method, but it didn't work:
if id == self.ID_SCROLLGRP: self.ua.LayoutChanged() self.LayoutChanged(self.ID_SCROLLGRP)
There doesn't seem to be any id or data passed to the Command method when the group is scrolled.
I also tried listening for the BFM_SCROLLGROUP_SCROLLED message:
BFM_SCROLLGROUP_SCROLLED
def Message(self, msg, result): if msg.GetId() == c4d.BFM_SCROLLGROUP_SCROLLED: self.ua.LayoutChanged() self.LayoutChanged(self.ID_SCROLLGRP) return c4d.gui.GeDialog.Message(self, msg, result)
This created a loop and froze Cinema 4D (I believe because self.LayoutChanged(self.ID_SCROLLGRP) may also be sending this Message?).
self.LayoutChanged(self.ID_SCROLLGRP)
Can you please help me understand how to redraw the Scrollgroup & GeUserArea on scroll? Thank you!
Hi @blastframe, just to inform you I didn't forget you,
I thinks this may be another issue related to GeUserArea wrong coordinate topic:
However, I still needs some time to investigate from where it come. I will keep you updated. Cheers, Maxime.
@m_adam Thank you very much for all your help, Maxime!
Yes, after you answered my question here, I used that workaround for the UserArea from this issue.
It is working, but I'd rather the safer solution you're seeking.
All the best.
@m_adam Thank you, Maxime, for going to this effort.