]>
Commit | Line | Data |
---|---|---|
f6bcfd97 | 1 | |
8fa876ca RD |
2 | import random |
3 | ||
4 | import wx | |
5 | import wx.grid as gridlib | |
f6bcfd97 BP |
6 | |
7 | #--------------------------------------------------------------------------- | |
8 | ||
8fa876ca | 9 | class MyCustomRenderer(gridlib.PyGridCellRenderer): |
f6bcfd97 | 10 | def __init__(self): |
8fa876ca | 11 | gridlib.PyGridCellRenderer.__init__(self) |
f6bcfd97 BP |
12 | |
13 | def Draw(self, grid, attr, dc, rect, row, col, isSelected): | |
372bde9b RD |
14 | dc.SetBackgroundMode(wx.SOLID) |
15 | dc.SetBrush(wx.Brush(wx.BLACK, wx.SOLID)) | |
16 | dc.SetPen(wx.TRANSPARENT_PEN) | |
fbd5dd1d | 17 | dc.DrawRectangleRect(rect) |
f6bcfd97 | 18 | |
8fa876ca | 19 | dc.SetBackgroundMode(wx.TRANSPARENT) |
f6bcfd97 BP |
20 | dc.SetFont(attr.GetFont()) |
21 | ||
22 | text = grid.GetCellValue(row, col) | |
fbd5dd1d | 23 | colors = ["RED", "WHITE", "SKY BLUE"] |
f6bcfd97 BP |
24 | x = rect.x + 1 |
25 | y = rect.y + 1 | |
8fa876ca | 26 | |
f6bcfd97 BP |
27 | for ch in text: |
28 | dc.SetTextForeground(random.choice(colors)) | |
fbd5dd1d | 29 | dc.DrawText(ch, (x, y)) |
f6bcfd97 BP |
30 | w, h = dc.GetTextExtent(ch) |
31 | x = x + w | |
32 | if x > rect.right - 5: | |
33 | break | |
34 | ||
35 | ||
36 | def GetBestSize(self, grid, attr, dc, row, col): | |
37 | text = grid.GetCellValue(row, col) | |
38 | dc.SetFont(attr.GetFont()) | |
39 | w, h = dc.GetTextExtent(text) | |
8fa876ca | 40 | return wx.Size(w, h) |
f6bcfd97 BP |
41 | |
42 | ||
43 | def Clone(self): | |
44 | return MyCustomRenderer() | |
45 | ||
46 | ||
47 | #--------------------------------------------------------------------------- | |
48 | ||
49 | rendererDemoData = [ | |
8fa876ca RD |
50 | ('GridCellStringRenderer\n(the default)', 'this is a text value', gridlib.GridCellStringRenderer, ()), |
51 | ('GridCellNumberRenderer', '12345', gridlib.GridCellNumberRenderer, ()), | |
52 | ('GridCellFloatRenderer', '1234.5678', gridlib.GridCellFloatRenderer, (6,2)), | |
53 | ('GridCellBoolRenderer', '1', gridlib.GridCellBoolRenderer, ()), | |
f6bcfd97 BP |
54 | ('MyCustomRenderer', 'This is my renderer', MyCustomRenderer, ()), |
55 | ] | |
56 | ||
57 | editorDemoData = [ | |
8fa876ca RD |
58 | ('GridCellTextEditor\n(the default)', 'Here is some more text', gridlib.GridCellTextEditor, ()), |
59 | ('GridCellNumberEditor\nwith min,max', '101', gridlib.GridCellNumberEditor, (5, 10005)), | |
60 | ('GridCellNumberEditor\nwithout bounds', '101', gridlib.GridCellNumberEditor, ()), | |
61 | ('GridCellFloatEditor', '1234.5678', gridlib.GridCellFloatEditor, ()), | |
62 | ('GridCellBoolEditor', '1', gridlib.GridCellBoolEditor, ()), | |
63 | ('GridCellChoiceEditor', 'one', gridlib.GridCellChoiceEditor, (['one', 'two', 'three', 'four', | |
f6bcfd97 | 64 | 'kick', 'Microsoft', 'out the', |
1e4a197e | 65 | 'door'], False)), |
f6bcfd97 BP |
66 | ] |
67 | ||
f6bcfd97 | 68 | comboDemoData = [ |
8fa876ca RD |
69 | ('GridCellNumberRenderer\nGridCellNumberEditor', '20792', gridlib.GridCellNumberRenderer, gridlib.GridCellNumberEditor), |
70 | ('GridCellBoolRenderer\nGridCellBoolEditor', '1', gridlib.GridCellBoolRenderer, gridlib.GridCellBoolEditor), | |
f6bcfd97 BP |
71 | ] |
72 | ||
73 | ||
8fa876ca | 74 | class EditorsAndRenderersGrid(gridlib.Grid): |
f6bcfd97 | 75 | def __init__(self, parent, log): |
8fa876ca | 76 | gridlib.Grid.__init__(self, parent, -1) |
f6bcfd97 BP |
77 | self.log = log |
78 | ||
79 | self.CreateGrid(25, 8) | |
80 | renCol = 1 | |
81 | edCol = 4 | |
82 | ||
83 | ||
84 | self.SetCellValue(0, renCol, '''\ | |
85 | Cell Renderers are used to draw | |
86 | the contents of the cell when they | |
87 | need to be refreshed. Different | |
88 | types of Renderers can be plugged in | |
89 | to different cells in the grid, it can | |
90 | even be automatically determined based | |
91 | on the type of data in the cell. | |
92 | ''') | |
93 | ||
94 | self.SetCellValue(0, edCol, '''\ | |
95 | Cell Editors are used when the | |
96 | value of the cell is edited by | |
97 | the user. An editor class is | |
98 | wrapped around a an object | |
99 | derived from wxControl and it | |
100 | implements some methods required | |
101 | to integrate with the grid. | |
102 | ''') | |
103 | ||
104 | self.SetCellValue(16, renCol, '''\ | |
105 | Here are some combinations of Editors and | |
106 | Renderers used together. | |
107 | ''') | |
108 | ||
109 | row = 2 | |
8fa876ca | 110 | |
f6bcfd97 | 111 | for label, value, renderClass, args in rendererDemoData: |
fbd5dd1d | 112 | renderer = renderClass(*args) |
f6bcfd97 BP |
113 | self.SetCellValue(row, renCol, label) |
114 | self.SetCellValue(row, renCol+1, value) | |
115 | self.SetCellRenderer(row, renCol+1, renderer) | |
116 | row = row + 2 | |
117 | ||
118 | ||
119 | row = 2 | |
8fa876ca | 120 | |
f6bcfd97 | 121 | for label, value, editorClass, args in editorDemoData: |
fbd5dd1d | 122 | editor = editorClass(*args) |
f6bcfd97 BP |
123 | self.SetCellValue(row, edCol, label) |
124 | self.SetCellValue(row, edCol+1, value) | |
125 | self.SetCellEditor(row, edCol+1, editor) | |
126 | row = row + 2 | |
127 | ||
128 | ||
129 | row = 18 | |
8fa876ca | 130 | |
f6bcfd97 BP |
131 | for label, value, renClass, edClass in comboDemoData: |
132 | self.SetCellValue(row, renCol, label) | |
133 | self.SetCellValue(row, renCol+1, value) | |
fbd5dd1d RD |
134 | editor = edClass() |
135 | renderer = renClass() | |
f6bcfd97 BP |
136 | self.SetCellEditor(row, renCol+1, editor) |
137 | self.SetCellRenderer(row, renCol+1, renderer) | |
138 | row = row + 2 | |
139 | ||
f6bcfd97 | 140 | font = self.GetFont() |
8fa876ca RD |
141 | font.SetWeight(wx.BOLD) |
142 | attr = gridlib.GridCellAttr() | |
f6bcfd97 | 143 | attr.SetFont(font) |
8fa876ca | 144 | attr.SetBackgroundColour(wx.LIGHT_GREY) |
1e4a197e | 145 | attr.SetReadOnly(True) |
8fa876ca | 146 | attr.SetAlignment(wx.RIGHT, -1) |
f6bcfd97 | 147 | self.SetColAttr(renCol, attr) |
9416aa89 | 148 | attr.IncRef() |
f6bcfd97 BP |
149 | self.SetColAttr(edCol, attr) |
150 | ||
151 | # There is a bug in wxGTK for this method... | |
1e4a197e RD |
152 | self.AutoSizeColumns(True) |
153 | self.AutoSizeRows(True) | |
f6bcfd97 | 154 | |
8fa876ca | 155 | self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.OnLeftDClick) |
f6bcfd97 BP |
156 | |
157 | ||
158 | # I do this because I don't like the default behaviour of not starting the | |
159 | # cell editor on double clicks, but only a second click. | |
160 | def OnLeftDClick(self, evt): | |
161 | if self.CanEnableCellControl(): | |
162 | self.EnableCellEditControl() | |
163 | ||
164 | ||
165 | #--------------------------------------------------------------------------- | |
166 | ||
8fa876ca | 167 | class TestFrame(wx.Frame): |
f6bcfd97 | 168 | def __init__(self, parent, log): |
8fa876ca | 169 | wx.Frame.__init__(self, parent, -1, "Editors and Renderers Demo", size=(640,480)) |
f6bcfd97 BP |
170 | grid = EditorsAndRenderersGrid(self, log) |
171 | ||
172 | ||
173 | ||
174 | #--------------------------------------------------------------------------- | |
175 | ||
176 | if __name__ == '__main__': | |
177 | import sys | |
8fa876ca | 178 | app = wx.PySimpleApp() |
f6bcfd97 | 179 | frame = TestFrame(None, sys.stdout) |
1e4a197e | 180 | frame.Show(True) |
f6bcfd97 BP |
181 | app.MainLoop() |
182 | ||
183 | ||
184 | #--------------------------------------------------------------------------- |