Fixed transparency issues in Windows by using a GraphicsContext. Changed background to white.

- The white background is a workaround for not being able to set the
exact color of gray for the XY/Z widgets.
master
Duane Johnson 2011-11-08 09:37:35 -06:00
parent 39a99314b3
commit 50d340f900
5 changed files with 44 additions and 74 deletions

View File

@ -1,6 +1,6 @@
"""
BufferedCanvas -- Double-buffered, flicker-free canvas widget
Copyright (C) 2005, 2006 Daniel Keep
BufferedCanvas -- flicker-free canvas widget
Copyright (C) 2005, 2006 Daniel Keep, 2011 Duane Johnson
To use this widget, just override or replace the draw method.
This will be called whenever the widget size changes, or when
@ -46,16 +46,12 @@ import wx
class BufferedCanvas(wx.Panel):
"""
Implements a double-buffered, flicker-free canvas widget.
Implements a flicker-free canvas widget.
Standard usage is to subclass this class, and override the
draw method. The draw method is passed a device context, which
should be used to do your drawing.
Also, you should NOT call dc.BeginDrawing() and dc.EndDrawing() --
these methods are automatically called for you, although you still
need to manually clear the device context.
If you want to force a redraw (for whatever reason), you should
call the update method. This is because the draw method is never
called as a result of an EVT_PAINT event.
@ -77,16 +73,12 @@ class BufferedCanvas(wx.Panel):
# Bind events
self.Bind(wx.EVT_PAINT, self.onPaint)
self.Bind(wx.EVT_SIZE, self.onSize)
# Disable background erasing (flicker-licious)
def disable_event(*pargs,**kwargs):
pass # the sauce, please
self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event)
# Ensure that the buffers are setup correctly
self.onSize(None)
##
## General methods
##
@ -97,27 +89,11 @@ class BufferedCanvas(wx.Panel):
"""
pass
def flip(self):
"""
Flips the front and back buffers.
"""
self.buffer,self.backbuffer = self.backbuffer,self.buffer
self.Refresh()
def update(self):
"""
Causes the canvas to be updated.
"""
dc = wx.MemoryDC()
width,height = self.getWidthHeight()
self.backbuffer = wx.EmptyBitmapRGBA(width,height,alpha=0)
dc.SelectObject(self.backbuffer)
dc.BeginDrawing()
self.draw(dc)
dc.EndDrawing()
self.flip()
self.Refresh()
def getWidthHeight(self):
width,height = self.GetClientSizeTuple()
@ -133,15 +109,9 @@ class BufferedCanvas(wx.Panel):
def onPaint(self, event):
# Blit the front buffer to the screen
dc = wx.BufferedPaintDC(self, self.buffer)
def onSize(self, event):
# Here we need to create a new off-screen buffer to hold
# the in-progress drawings on.
w, h = self.getWidthHeight()
self.buffer = wx.EmptyBitmapRGBA(w, h, alpha=0)
self.backbuffer = wx.EmptyBitmapRGBA(w, h, alpha=0)
# Now update the screen
self.update()
w, h = self.GetClientSizeTuple()
if not w or not h:
return
else:
dc = wx.BufferedPaintDC(self)
self.draw(dc, w, h)

View File

@ -120,6 +120,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.starttime=0
self.curlayer=0
self.cur_button=None
self.SetBackgroundColour("white")
def startcb(self):
self.starttime=time.time()

View File

@ -14,6 +14,7 @@ class MyFrame(wx.Frame):
sizer.Add(self.z, flag=wx.ALIGN_CENTER)
self.SetSizer(sizer)
self.SetBackgroundColour("white")
def moveXY(self, x, y):
print "got x", x, 'y', y

View File

@ -13,7 +13,7 @@ class XYButtons(BufferedCanvas):
keypad_positions = {
0: (126, 126),
1: (100, 100),
2: (78, 78),
2: (80, 80),
3: (60, 60)
}
concentric_circle_radii = [15, 55, 86, 117, 142]
@ -101,7 +101,7 @@ class XYButtons(BufferedCanvas):
def mouseOverKeypad(self, mpos):
for idx, kpos in XYButtons.keypad_positions.items():
rect = wx.Rect(kpos[0], kpos[1], 44, 32)
rect = wx.Rect(kpos[0], kpos[1], self.keypad_bmp.GetWidth(), self.keypad_bmp.GetHeight())
if rect.Contains(mpos):
return idx
return None
@ -144,28 +144,19 @@ class XYButtons(BufferedCanvas):
self.concentric = None
self.update()
def drawPartialPie(self, dc, center, r1, r2, angle1, angle2):
def drawPartialPie(self, gc, center, r1, r2, angle1, angle2):
parts = 64
angle_dist = angle2 - angle1
angle_inc = angle_dist / parts
p1 = wx.Point(center.x + r1*math.cos(angle1), center.y + r1*math.sin(angle1))
p2 = wx.Point(center.x + r2*math.cos(angle1), center.y + r2*math.sin(angle1))
p3 = wx.Point(center.x + r2*math.cos(angle2), center.y + r2*math.sin(angle2))
p4 = wx.Point(center.x + r1*math.cos(angle2), center.y + r1*math.sin(angle2))
points = [p1, p2]
points.extend([wx.Point(
center.x + r1*math.cos(angle1+i*angle_inc),
center.y + r1*math.sin(angle1+i*angle_inc)) for i in range(0, parts)])
# points.extend([p3])
points.extend([wx.Point(
center.x + r2*math.cos(angle1+i*angle_inc),
center.y + r2*math.sin(angle1+i*angle_inc)) for i in range(parts, 0, -1)])
dc.DrawPolygon(points)
path = gc.CreatePath()
path.MoveToPoint(p1.x, p1.y)
path.AddArc(center.x, center.y, r1, angle1, angle2, True)
path.AddArc(center.x, center.y, r2, angle2, angle1, False)
path.AddLineToPoint(p1.x, p1.y)
gc.DrawPath(path)
def distanceToLine(self, pos, x1, y1, x2, y2):
xlen = x2 - x1
@ -174,7 +165,7 @@ class XYButtons(BufferedCanvas):
pylen = y1 - pos.y
return abs(xlen*pylen-ylen*pxlen)/math.sqrt(xlen**2+ylen**2)
def highlightQuadrant(self, dc, quadrant, concentric):
def highlightQuadrant(self, gc, quadrant, concentric):
assert(quadrant >= 0 and quadrant <= 3)
assert(concentric >= 0 and concentric <= 3)
@ -197,21 +188,24 @@ class XYButtons(BufferedCanvas):
r1 = XYButtons.concentric_circle_radii[concentric]
r2 = XYButtons.concentric_circle_radii[concentric+1]
self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
def draw(self, dc):
self.drawPartialPie(gc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
def draw(self, dc, w, h):
dc.Clear()
gc = wx.GraphicsContext.Create(dc)
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
dc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
dc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
dc.DrawBitmap(self.bg_bmp, 0, 0)
gc.DrawBitmap(self.bg_bmp, 0, 0, self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
if self.quadrant != None and self.concentric != None:
self.highlightQuadrant(dc, self.quadrant, self.concentric)
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
gc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
self.highlightQuadrant(gc, self.quadrant, self.concentric)
if self.keypad_idx >= 0:
pos = XYButtons.keypad_positions[self.keypad_idx]
dc.DrawBitmap(self.keypad_bmp, pos[0], pos[1])
gc.DrawBitmap(self.keypad_bmp, pos[0], pos[1], self.keypad_bmp.GetWidth(), self.keypad_bmp.GetHeight())
return True

View File

@ -38,7 +38,7 @@ class ZButtons(BufferedCanvas):
idx += 1
return None
def highlight(self, dc, rng, dir):
def highlight(self, gc, rng, dir):
assert(rng >= -1 and rng <= 3)
assert(dir >= -1 and dir <= 1)
@ -49,7 +49,8 @@ class ZButtons(BufferedCanvas):
k = 1 if dir > 0 else 0
y = ZButtons.center[1] - (dir * ZButtons.button_ydistances[rng+k])
h = ZButtons.button_ydistances[rng+1] - ZButtons.button_ydistances[rng]
dc.DrawRectangle(x, y, w, h)
gc.DrawRoundedRectangle(x, y, w, h, 4)
# gc.DrawRectangle(x, y, w, h)
# self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
def getRangeDir(self, pos):
@ -78,13 +79,16 @@ class ZButtons(BufferedCanvas):
self.direction = None
self.update()
def draw(self, dc):
dc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
dc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
def draw(self, dc, w, h):
dc.Clear()
gc = wx.GraphicsContext.Create(dc)
dc.DrawBitmap(self.bg_bmp, 0, 0)
gc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
gc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
gc.DrawBitmap(self.bg_bmp, 0, 0, self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
if self.range != None and self.direction != None:
self.highlight(dc, self.range, self.direction)
self.highlight(gc, self.range, self.direction)
return True