1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#!/usr/bin/env python
import wx
import images
#----------------------------------------------------------------------
class TestFrame(wx.Frame):
def __init__(self, parent, log):
self.log = log
wx.Frame.__init__(self, parent, -1, "Shaped Window",
style =
wx.FRAME_SHAPED
| wx.SIMPLE_BORDER
| wx.FRAME_NO_TASKBAR
| wx.STAY_ON_TOP
)
self.hasShape = False
self.delta = (0,0)
self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Bind(wx.EVT_RIGHT_UP, self.OnExit)
self.Bind(wx.EVT_PAINT, self.OnPaint)
# Load the image and ensure it has a Mask, (rather than an alpha channel)
img = images.Vippi.GetImage()
if img.HasAlpha():
img.ConvertAlphaToMask()
# Convert it to a wx.Bitmap, which will be used in SetWindowShape, and
# in OnPaint below.
self.bmp = wx.Bitmap(img)
w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
self.SetClientSize( (w, h) )
self.SetToolTip("Right-click to close the window\n"
"Double-click the image to set/unset the window shape")
if wx.Platform == "__WXGTK__":
# wxGTK requires that the window be created before you can
# set its shape, so delay the call to SetWindowShape until
# this event.
self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
else:
# On wxMSW and wxMac the window has already been created, so go for it.
self.SetWindowShape()
dc = wx.ClientDC(self)
dc.DrawBitmap(self.bmp, 0,0, True)
def SetWindowShape(self, *evt):
# Use the bitmap's mask to create a wx.Region
r = wx.Region(self.bmp)
# NOTE: Starting in 4.1 you can also get a wx.Region directly from
# a wx.Image, so you can save a step if you don't need it as a wx.Bitmap
# for anything else.
#r = self.img.ConvertToRegion()
# Use the region to set the frame's shape
self.hasShape = self.SetShape(r)
def OnDoubleClick(self, evt):
if self.hasShape:
self.SetShape(wx.Region())
self.hasShape = False
else:
self.SetWindowShape()
def OnPaint(self, evt):
dc = wx.PaintDC(self)
dc.DrawBitmap(self.bmp, 0,0, True)
def OnExit(self, evt):
self.Close()
def OnLeftDown(self, evt):
self.CaptureMouse()
x, y = self.ClientToScreen(evt.GetPosition())
originx, originy = self.GetPosition()
dx = x - originx
dy = y - originy
self.delta = ((dx, dy))
def OnLeftUp(self, evt):
if self.HasCapture():
self.ReleaseMouse()
def OnMouseMove(self, evt):
if evt.Dragging() and evt.LeftIsDown():
x, y = self.ClientToScreen(evt.GetPosition())
fp = (x - self.delta[0], y - self.delta[1])
self.Move(fp)
#---------------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
b = wx.Button(self, -1, "Show the ShapedWindow sample", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
win = TestFrame(self, self.log)
win.Show(True)
#---------------------------------------------------------------------------
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
#----------------------------------------------------------------------
overview = """<html><body>
<h2><center>Shaped Window</center></h2>
Top level windows now have a SetShape method that lets you set a
non-rectangular shape for the window using a wxRegion. All pixels
outside of the region will not be drawn and the window will not be
sensitive to the mouse in those areas either.
</body></html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
|