Commit 50d340f9 authored by Duane Johnson's avatar Duane Johnson

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.
parent 39a99314
""" """
BufferedCanvas -- Double-buffered, flicker-free canvas widget BufferedCanvas -- flicker-free canvas widget
Copyright (C) 2005, 2006 Daniel Keep Copyright (C) 2005, 2006 Daniel Keep, 2011 Duane Johnson
To use this widget, just override or replace the draw method. To use this widget, just override or replace the draw method.
This will be called whenever the widget size changes, or when This will be called whenever the widget size changes, or when
...@@ -46,16 +46,12 @@ import wx ...@@ -46,16 +46,12 @@ import wx
class BufferedCanvas(wx.Panel): 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 Standard usage is to subclass this class, and override the
draw method. The draw method is passed a device context, which draw method. The draw method is passed a device context, which
should be used to do your drawing. 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 If you want to force a redraw (for whatever reason), you should
call the update method. This is because the draw method is never call the update method. This is because the draw method is never
called as a result of an EVT_PAINT event. called as a result of an EVT_PAINT event.
...@@ -77,16 +73,12 @@ class BufferedCanvas(wx.Panel): ...@@ -77,16 +73,12 @@ class BufferedCanvas(wx.Panel):
# Bind events # Bind events
self.Bind(wx.EVT_PAINT, self.onPaint) self.Bind(wx.EVT_PAINT, self.onPaint)
self.Bind(wx.EVT_SIZE, self.onSize)
# Disable background erasing (flicker-licious) # Disable background erasing (flicker-licious)
def disable_event(*pargs,**kwargs): def disable_event(*pargs,**kwargs):
pass # the sauce, please pass # the sauce, please
self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event) self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event)
# Ensure that the buffers are setup correctly
self.onSize(None)
## ##
## General methods ## General methods
## ##
...@@ -97,27 +89,11 @@ class BufferedCanvas(wx.Panel): ...@@ -97,27 +89,11 @@ class BufferedCanvas(wx.Panel):
""" """
pass pass
def flip(self):
"""
Flips the front and back buffers.
"""
self.buffer,self.backbuffer = self.backbuffer,self.buffer
self.Refresh()
def update(self): def update(self):
""" """
Causes the canvas to be updated. Causes the canvas to be updated.
""" """
dc = wx.MemoryDC() self.Refresh()
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()
def getWidthHeight(self): def getWidthHeight(self):
width,height = self.GetClientSizeTuple() width,height = self.GetClientSizeTuple()
...@@ -133,15 +109,9 @@ class BufferedCanvas(wx.Panel): ...@@ -133,15 +109,9 @@ class BufferedCanvas(wx.Panel):
def onPaint(self, event): def onPaint(self, event):
# Blit the front buffer to the screen # Blit the front buffer to the screen
dc = wx.BufferedPaintDC(self, self.buffer) w, h = self.GetClientSizeTuple()
if not w or not h:
return
def onSize(self, event): else:
# Here we need to create a new off-screen buffer to hold dc = wx.BufferedPaintDC(self)
# the in-progress drawings on. self.draw(dc, w, h)
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()
...@@ -120,6 +120,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole): ...@@ -120,6 +120,7 @@ class PronterWindow(wx.Frame,pronsole.pronsole):
self.starttime=0 self.starttime=0
self.curlayer=0 self.curlayer=0
self.cur_button=None self.cur_button=None
self.SetBackgroundColour("white")
def startcb(self): def startcb(self):
self.starttime=time.time() self.starttime=time.time()
......
...@@ -14,6 +14,7 @@ class MyFrame(wx.Frame): ...@@ -14,6 +14,7 @@ class MyFrame(wx.Frame):
sizer.Add(self.z, flag=wx.ALIGN_CENTER) sizer.Add(self.z, flag=wx.ALIGN_CENTER)
self.SetSizer(sizer) self.SetSizer(sizer)
self.SetBackgroundColour("white")
def moveXY(self, x, y): def moveXY(self, x, y):
print "got x", x, 'y', y print "got x", x, 'y', y
......
...@@ -13,7 +13,7 @@ class XYButtons(BufferedCanvas): ...@@ -13,7 +13,7 @@ class XYButtons(BufferedCanvas):
keypad_positions = { keypad_positions = {
0: (126, 126), 0: (126, 126),
1: (100, 100), 1: (100, 100),
2: (78, 78), 2: (80, 80),
3: (60, 60) 3: (60, 60)
} }
concentric_circle_radii = [15, 55, 86, 117, 142] concentric_circle_radii = [15, 55, 86, 117, 142]
...@@ -101,7 +101,7 @@ class XYButtons(BufferedCanvas): ...@@ -101,7 +101,7 @@ class XYButtons(BufferedCanvas):
def mouseOverKeypad(self, mpos): def mouseOverKeypad(self, mpos):
for idx, kpos in XYButtons.keypad_positions.items(): 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): if rect.Contains(mpos):
return idx return idx
return None return None
...@@ -144,28 +144,19 @@ class XYButtons(BufferedCanvas): ...@@ -144,28 +144,19 @@ class XYButtons(BufferedCanvas):
self.concentric = None self.concentric = None
self.update() self.update()
def drawPartialPie(self, dc, center, r1, r2, angle1, angle2): def drawPartialPie(self, gc, center, r1, r2, angle1, angle2):
parts = 64 parts = 64
angle_dist = angle2 - angle1 angle_dist = angle2 - angle1
angle_inc = angle_dist / parts angle_inc = angle_dist / parts
p1 = wx.Point(center.x + r1*math.cos(angle1), center.y + r1*math.sin(angle1)) 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]) path = gc.CreatePath()
path.MoveToPoint(p1.x, p1.y)
points.extend([wx.Point( path.AddArc(center.x, center.y, r1, angle1, angle2, True)
center.x + r2*math.cos(angle1+i*angle_inc), path.AddArc(center.x, center.y, r2, angle2, angle1, False)
center.y + r2*math.sin(angle1+i*angle_inc)) for i in range(parts, 0, -1)]) path.AddLineToPoint(p1.x, p1.y)
dc.DrawPolygon(points) gc.DrawPath(path)
def distanceToLine(self, pos, x1, y1, x2, y2): def distanceToLine(self, pos, x1, y1, x2, y2):
xlen = x2 - x1 xlen = x2 - x1
...@@ -174,7 +165,7 @@ class XYButtons(BufferedCanvas): ...@@ -174,7 +165,7 @@ class XYButtons(BufferedCanvas):
pylen = y1 - pos.y pylen = y1 - pos.y
return abs(xlen*pylen-ylen*pxlen)/math.sqrt(xlen**2+ylen**2) 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(quadrant >= 0 and quadrant <= 3)
assert(concentric >= 0 and concentric <= 3) assert(concentric >= 0 and concentric <= 3)
...@@ -197,21 +188,24 @@ class XYButtons(BufferedCanvas): ...@@ -197,21 +188,24 @@ class XYButtons(BufferedCanvas):
r1 = XYButtons.concentric_circle_radii[concentric] r1 = XYButtons.concentric_circle_radii[concentric]
r2 = XYButtons.concentric_circle_radii[concentric+1] 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)
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
def draw(self, dc, w, h):
dc.Clear()
gc = wx.GraphicsContext.Create(dc)
dc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4)) center = wx.Point(XYButtons.center[0], XYButtons.center[1])
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: 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: if self.keypad_idx >= 0:
pos = XYButtons.keypad_positions[self.keypad_idx] 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 return True
...@@ -38,7 +38,7 @@ class ZButtons(BufferedCanvas): ...@@ -38,7 +38,7 @@ class ZButtons(BufferedCanvas):
idx += 1 idx += 1
return None return None
def highlight(self, dc, rng, dir): def highlight(self, gc, rng, dir):
assert(rng >= -1 and rng <= 3) assert(rng >= -1 and rng <= 3)
assert(dir >= -1 and dir <= 1) assert(dir >= -1 and dir <= 1)
...@@ -49,7 +49,8 @@ class ZButtons(BufferedCanvas): ...@@ -49,7 +49,8 @@ class ZButtons(BufferedCanvas):
k = 1 if dir > 0 else 0 k = 1 if dir > 0 else 0
y = ZButtons.center[1] - (dir * ZButtons.button_ydistances[rng+k]) y = ZButtons.center[1] - (dir * ZButtons.button_ydistances[rng+k])
h = ZButtons.button_ydistances[rng+1] - ZButtons.button_ydistances[rng] 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) # self.drawPartialPie(dc, center, r1-inner_ring_radius, r2-inner_ring_radius, a1+fudge, a2-fudge)
def getRangeDir(self, pos): def getRangeDir(self, pos):
...@@ -78,13 +79,16 @@ class ZButtons(BufferedCanvas): ...@@ -78,13 +79,16 @@ class ZButtons(BufferedCanvas):
self.direction = None self.direction = None
self.update() self.update()
def draw(self, dc): def draw(self, dc, w, h):
dc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4)) dc.Clear()
dc.SetBrush(wx.Brush(wx.Colour(0,0,0,128))) 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: if self.range != None and self.direction != None:
self.highlight(dc, self.range, self.direction) self.highlight(gc, self.range, self.direction)
return True return True
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment