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
parent
39a99314b3
commit
50d340f900
|
@ -1,6 +1,6 @@
|
||||||
"""
|
"""
|
||||||
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
|
||||||
|
|
||||||
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):
|
||||||
|
|
||||||
# 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):
|
||||||
"""
|
"""
|
||||||
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):
|
||||||
|
|
||||||
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):
|
||||||
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()
|
||||||
|
|
1
test.py
1
test.py
|
@ -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
|
||||||
|
|
48
xybuttons.py
48
xybuttons.py
|
@ -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):
|
||||||
|
|
||||||
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):
|
||||||
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]
|
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 + r1*math.cos(angle1+i*angle_inc),
|
path.AddArc(center.x, center.y, r2, angle2, angle1, False)
|
||||||
center.y + r1*math.sin(angle1+i*angle_inc)) for i in range(0, parts)])
|
path.AddLineToPoint(p1.x, p1.y)
|
||||||
|
gc.DrawPath(path)
|
||||||
# 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)
|
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
def draw(self, dc, w, h):
|
||||||
|
dc.Clear()
|
||||||
|
gc = wx.GraphicsContext.Create(dc)
|
||||||
|
|
||||||
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
|
center = wx.Point(XYButtons.center[0], XYButtons.center[1])
|
||||||
|
|
||||||
dc.SetPen(wx.Pen(wx.Colour(100,100,100,172), 4))
|
gc.DrawBitmap(self.bg_bmp, 0, 0, self.bg_bmp.GetWidth(), self.bg_bmp.GetHeight())
|
||||||
dc.SetBrush(wx.Brush(wx.Colour(0,0,0,128)))
|
|
||||||
|
|
||||||
dc.DrawBitmap(self.bg_bmp, 0, 0)
|
|
||||||
|
|
||||||
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
|
||||||
|
|
18
zbuttons.py
18
zbuttons.py
|
@ -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):
|
||||||
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):
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue