Ironically this discussion seems to be leading back to the topic of the original poster’s subject line “dc.Clear(): is this a bug or am I doing something wrong?”. I think there may be a bug in .Clear(dc) not taking into account of the scroll, even though canvas.PrepareDC(dc) has been called.
diagram.Clear(dc) - Only clears the top, physical screen area -
pointless in a situation where you want to clear the contents of a
larger virtual sized ogl shapecanvas with scrollbars.
What dc are you passing it? Do you do canvas.PrepareDC(dc) on it?
Yes I am calling canvas.PrepareDC(dc)
Run the following code and when you press the “c” key you will see how .Clear(dc) always clears the top, physical screen area regardless of the scroll situation.
import wx
import wx.lib.ogl as ogl
import random
import time
class MyShapeCanvas(ogl.ShapeCanvas):
def __init__(self, parent, frame):
ogl.ShapeCanvas.__init__(self, parent)
self.frame = frame
self.SetBackgroundColour("LIGHT BLUE")
self.SetDiagram(ogl.Diagram())
self.GetDiagram().SetCanvas(self)
WINDOW_SIZE = (600, 400)
VIRTUAL_SIZE_X = 1200
VIRTUAL_SIZE_Y = 800
class MainApp(wx.App):
def OnInit(self):
self.frame = wx.Frame(None, -1, "test2 scroll drawing", pos=(450,450), size=WINDOW_SIZE,
style=wx.NO_FULL_REPAINT_ON_RESIZE|wx.DEFAULT_FRAME_STYLE)
self.shapecanvas = MyShapeCanvas(self.frame, self.frame)
self.shapecanvas.frame = self.frame
self.shapecanvas.SetScrollbars(1, 1, VIRTUAL_SIZE_X, VIRTUAL_SIZE_Y)
self.Bind(wx.EVT_CHAR, self.onKeyChar)
ogl.OGLInitialize() # creates some pens and brushes that the OGL library uses.
self.frame.Show(True)
wx.CallAfter(self.BootStrap)
return True
def BootStrap(self):
# Add some shapes
y = 30
for x in range(30, 1200, 70):
shape = ogl.RectangleShape( 60, 60 )
shape.SetX(x)
shape.SetY(y)
self.shapecanvas.AddShape( shape )
y += 70
self.shapecanvas.GetDiagram().ShowAll( 1 )
def onKeyChar(self, event):
canvas = self.shapecanvas
keycode = chr(event.GetKeyCode())
if keycode == 'c':
# The .Clear(dc) below always clears the top, physical size window
# area - never the scrolled physical size window visible at the
# moment (even though I have called prepareDC !!). This I think may
# be a bug?
dc = wx.ClientDC(canvas)
canvas.PrepareDC(dc)
canvas.GetDiagram().Clear(dc)
def main():
application = MainApp(0)
application.MainLoop()
if name == ‘main’:
main()
In the above demo, as you scroll up and down, the newly exposed regions are repainted nicely. But when you hit “c” you will see that .Clear(dc) doesn’t clear the visible physical screen area taking into account the scroll. It always clears the topmost visible physical screen area.
When those portions are scrolled into view there should be paint events
with the newly exposed regions in the update region, and so those
regions should be repainted at that time. Unless there is more going on
there than just dc.Clear that I’m not remembering at the moment, the
unseen areas really should not need to be explicitly cleared.
Ok yes I agree. Originally I thought that shapecanvas.Clear(dc) should perhaps clear the whole virtualsized canvas - but now I see that that it should only be clearing the visible area, taking into account of the scroll. As you say, the newly exposed regions will look after themselves with the relevant paint events being triggered.
Trouble is, shapecanvas.Clear(dc) doesn’t take into account the scroll - as my demo shows.
P.S. Thanks for your comments re buffers and possible enhancements to OGL. My understanding of wxpython hasn’t really progressed into buffering yet, so I can’t comment. I am running on windows 7, wx-2.8-msw-unicode, python 2.7 and am assuming there is some sort of double buffering I am already getting for free though I don’t know whether mac os x and linux will perform the same - I do plan to port my app to those platforms so will soon discover this.
-Andy