| 1 | |
| 2 | import wx |
| 3 | import colorsys |
| 4 | from math import cos, sin, radians |
| 5 | |
| 6 | #---------------------------------------------------------------------- |
| 7 | |
| 8 | BASE = 80.0 # sizes used in shapes drawn below |
| 9 | BASE2 = BASE/2 |
| 10 | BASE4 = BASE/4 |
| 11 | |
| 12 | |
| 13 | class TestPanel(wx.Panel): |
| 14 | def __init__(self, parent, log): |
| 15 | self.log = log |
| 16 | wx.Panel.__init__(self, parent, -1) |
| 17 | |
| 18 | self.Bind(wx.EVT_PAINT, self.OnPaint) |
| 19 | |
| 20 | def OnPaint(self, evt): |
| 21 | dc = wx.PaintDC(self) |
| 22 | gc = wx.GraphicsContext.Create(dc) |
| 23 | |
| 24 | font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) |
| 25 | font.SetWeight(wx.BOLD) |
| 26 | gc.SetFont(font) |
| 27 | |
| 28 | # make a path that contains a circle and some lines, centered at 0,0 |
| 29 | path = gc.CreatePath() |
| 30 | path.AddCircle(0, 0, BASE2) |
| 31 | path.MoveToPoint(0, -BASE2) |
| 32 | path.AddLineToPoint(0, BASE2) |
| 33 | path.MoveToPoint(-BASE2, 0) |
| 34 | path.AddLineToPoint(BASE2, 0) |
| 35 | path.CloseSubpath() |
| 36 | path.AddRectangle(-BASE4, -BASE4/2, BASE2, BASE4) |
| 37 | |
| 38 | |
| 39 | # Now use that path to demonstrate various capbilites of the grpahics context |
| 40 | gc.PushState() # save current translation/scale/other state |
| 41 | gc.Translate(60, 75) # reposition the context origin |
| 42 | |
| 43 | gc.SetPen(wx.Pen("navy", 1)) |
| 44 | gc.SetBrush(wx.Brush("pink")) |
| 45 | |
| 46 | # show the difference between stroking, filling and drawing |
| 47 | for label, PathFunc in [("StrokePath", gc.StrokePath), |
| 48 | ("FillPath", gc.FillPath), |
| 49 | ("DrawPath", gc.DrawPath)]: |
| 50 | if "wxGTK" in wx.PlatformInfo: |
| 51 | w, h = dc.GetTextExtent(label) # NYI in Cairo context |
| 52 | else: |
| 53 | w, h = gc.GetTextExtent(label) |
| 54 | |
| 55 | gc.DrawText(label, -w/2, -BASE2-h) |
| 56 | PathFunc(path) |
| 57 | gc.Translate(2*BASE, 0) |
| 58 | |
| 59 | |
| 60 | gc.PopState() # restore saved state |
| 61 | gc.PushState() # save it again |
| 62 | gc.Translate(60, 200) # offset to the lower part of the window |
| 63 | |
| 64 | gc.DrawText("Scale", 0, -BASE2) |
| 65 | gc.Translate(0, 20) |
| 66 | |
| 67 | gc.SetBrush(wx.Brush(wx.Colour(178, 34, 34, 128))) # 128 == half transparent |
| 68 | for cnt in range(8): |
| 69 | gc.Scale(1.08, 1.08) # increase scale by 8% |
| 70 | gc.Translate(5,5) |
| 71 | gc.DrawPath(path) |
| 72 | |
| 73 | |
| 74 | gc.PopState() # restore saved state |
| 75 | gc.PushState() # save it again |
| 76 | gc.Translate(400, 200) |
| 77 | gc.DrawText("Rotate", 0, -BASE2) |
| 78 | |
| 79 | gc.Translate(0, 75) |
| 80 | for angle in range(0, 360, 30): |
| 81 | gc.PushState() # save this new current state so we can pop back to |
| 82 | # it at the end of the loop |
| 83 | r, g, b = [int(c * 255) for c in colorsys.hsv_to_rgb(float(angle)/360, 1, 1)] |
| 84 | gc.SetBrush(wx.Brush(wx.Colour(r, g, b, 64))) |
| 85 | |
| 86 | # use translate to artfully reposition each drawn path |
| 87 | gc.Translate(1.5 * BASE2 * cos(radians(angle)), |
| 88 | 1.5 * BASE2 * sin(radians(angle))) |
| 89 | |
| 90 | # use Rotate to rotate the path |
| 91 | gc.Rotate(radians(angle)) |
| 92 | |
| 93 | # now draw it |
| 94 | gc.DrawPath(path) |
| 95 | gc.PopState() |
| 96 | |
| 97 | gc.PopState() |
| 98 | |
| 99 | |
| 100 | #---------------------------------------------------------------------- |
| 101 | |
| 102 | def runTest(frame, nb, log): |
| 103 | win = TestPanel(nb, log) |
| 104 | return win |
| 105 | |
| 106 | #---------------------------------------------------------------------- |
| 107 | |
| 108 | |
| 109 | |
| 110 | overview = """<html><body> |
| 111 | <h2><center>wx.GraphicsContext and wx.GraphicsPath</center></h2> |
| 112 | |
| 113 | The new advanced 2D drawing API is implemented via the |
| 114 | wx.GraphicsContext and wx.GraphicsPath classes. They wrap GDI+ on |
| 115 | Windows, Cairo on wxGTK and CoreGraphics on OS X. They allow |
| 116 | path-based drawing with alpha-blending and anti-aliasing, and use a |
| 117 | floating point cooridnate system. |
| 118 | |
| 119 | <p>When viewing this sample pay attention to how the rounded edges are |
| 120 | smoothed with anti-aliased drawing, and how the shapes on the lower |
| 121 | half of the window are partially transparent, allowing you to see what |
| 122 | was drawn before. |
| 123 | |
| 124 | </body></html> |
| 125 | """ |
| 126 | |
| 127 | |
| 128 | |
| 129 | if __name__ == '__main__': |
| 130 | import sys,os |
| 131 | import run |
| 132 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) |
| 133 | |