]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/GridCustEditor.py
suppress an assert when a combobox receives WM_KILLFOCUS while it is being destroyed
[wxWidgets.git] / wxPython / demo / GridCustEditor.py
1
2 from wxPython.wx import *
3 from wxPython.grid import *
4
5 #---------------------------------------------------------------------------
6 class MyCellEditor(wxPyGridCellEditor):
7 """
8 This is a sample GridCellEditor that shows you how to make your own custom
9 grid editors. All the methods that can be overridden are show here. The
10 ones that must be overridden are marked with "*Must Override*" in the
11 docstring.
12
13 Notice that in order to call the base class version of these special
14 methods we use the method name preceded by "base_". This is because these
15 methods are "virtual" in C++ so if we try to call wxGridCellEditor.Create
16 for example, then when the wxPython extension module tries to call
17 ptr->Create(...) then it actually calls the derived class version which
18 looks up the method in this class and calls it, causing a recursion loop.
19 If you don't understand any of this, don't worry, just call the "base_"
20 version instead.
21 """
22 def __init__(self, log):
23 self.log = log
24 self.log.write("MyCellEditor ctor\n")
25 wxPyGridCellEditor.__init__(self)
26
27
28 def Create(self, parent, id, evtHandler):
29 """
30 Called to create the control, which must derive from wxControl.
31 *Must Override*
32 """
33 self.log.write("MyCellEditor: Create\n")
34 self._tc = wxTextCtrl(parent, id, "")
35 self._tc.SetInsertionPoint(0)
36 self.SetControl(self._tc)
37 if evtHandler:
38 self._tc.PushEventHandler(evtHandler)
39
40
41 def SetSize(self, rect):
42 """
43 Called to position/size the edit control within the cell rectangle.
44 If you don't fill the cell (the rect) then be sure to override
45 PaintBackground and do something meaningful there.
46 """
47 self.log.write("MyCellEditor: SetSize %s\n" % rect)
48 self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
49 wxSIZE_ALLOW_MINUS_ONE)
50
51
52 def Show(self, show, attr):
53 """
54 Show or hide the edit control. You can use the attr (if not None)
55 to set colours or fonts for the control.
56 """
57 self.log.write("MyCellEditor: Show(self, %s, %s)\n" % (show, attr))
58 self.base_Show(show, attr)
59
60
61 def PaintBackground(self, rect, attr):
62 """
63 Draws the part of the cell not occupied by the edit control. The
64 base class version just fills it with background colour from the
65 attribute. In this class the edit control fills the whole cell so
66 don't do anything at all in order to reduce flicker.
67 """
68 self.log.write("MyCellEditor: PaintBackground\n")
69
70
71 def BeginEdit(self, row, col, grid):
72 """
73 Fetch the value from the table and prepare the edit control
74 to begin editing. Set the focus to the edit control.
75 *Must Override*
76 """
77 self.log.write("MyCellEditor: BeginEdit (%d,%d)\n" % (row, col))
78 self.startValue = grid.GetTable().GetValue(row, col)
79 self._tc.SetValue(self.startValue)
80 self._tc.SetInsertionPointEnd()
81 self._tc.SetFocus()
82
83 # For this example, select the text
84 self._tc.SetSelection(0, self._tc.GetLastPosition())
85
86
87 def EndEdit(self, row, col, grid):
88 """
89 Complete the editing of the current cell. Returns true if the value
90 has changed. If necessary, the control may be destroyed.
91 *Must Override*
92 """
93 self.log.write("MyCellEditor: EndEdit (%d,%d)\n" % (row, col))
94 changed = false
95
96 val = self._tc.GetValue()
97 if val != self.startValue:
98 changed = true
99 grid.GetTable().SetValue(row, col, val) # update the table
100
101 self.startValue = ''
102 self._tc.SetValue('')
103 return changed
104
105
106 def Reset(self):
107 """
108 Reset the value in the control back to its starting value.
109 *Must Override*
110 """
111 self.log.write("MyCellEditor: Reset\n")
112 self._tc.SetValue(self.startValue)
113 self._tc.SetInsertionPointEnd()
114
115
116 def IsAcceptedKey(self, evt):
117 """
118 Return TRUE to allow the given key to start editing: the base class
119 version only checks that the event has no modifiers. F2 is special
120 and will always start the editor.
121 """
122 self.log.write("MyCellEditor: IsAcceptedKey: %d\n" % (evt.GetKeyCode()))
123
124 ## Oops, there's a bug here, we'll have to do it ourself..
125 ##return self.base_IsAcceptedKey(evt)
126
127 return (not (evt.ControlDown() or evt.AltDown()) and
128 evt.GetKeyCode() != WXK_SHIFT)
129
130
131 def StartingKey(self, evt):
132 """
133 If the editor is enabled by pressing keys on the grid, this will be
134 called to let the editor do something about that first key if desired.
135 """
136 self.log.write("MyCellEditor: StartingKey %d\n" % evt.GetKeyCode())
137 key = evt.GetKeyCode()
138 ch = None
139 if key in [WXK_NUMPAD0, WXK_NUMPAD1, WXK_NUMPAD2, WXK_NUMPAD3, WXK_NUMPAD4,
140 WXK_NUMPAD5, WXK_NUMPAD6, WXK_NUMPAD7, WXK_NUMPAD8, WXK_NUMPAD9]:
141 ch = ch = chr(ord('0') + key - WXK_NUMPAD0)
142
143 elif key < 256 and key >= 0 and chr(key) in string.printable:
144 ch = chr(key)
145 if not evt.ShiftDown():
146 ch = string.lower(ch)
147
148 if ch is not None:
149 # For this example, replace the text. Normally we would append it.
150 #self._tc.AppendText(ch)
151 self._tc.SetValue(ch)
152 else:
153 evt.Skip()
154
155
156 def StartingClick(self):
157 """
158 If the editor is enabled by clicking on the cell, this method will be
159 called to allow the editor to simulate the click on the control if
160 needed.
161 """
162 self.log.write("MyCellEditor: StartingClick\n")
163
164
165 def Destroy(self):
166 """final cleanup"""
167 self.log.write("MyCellEditor: Destroy\n")
168 self.base_Destroy()
169
170
171 def Clone(self):
172 """
173 Create a new object which is the copy of this one
174 *Must Override*
175 """
176 self.log.write("MyCellEditor: Clone\n")
177 return MyCellEditor(self.log)
178
179
180 #---------------------------------------------------------------------------
181 class GridEditorTest(wxGrid):
182 def __init__(self, parent, log):
183 wxGrid.__init__(self, parent, -1)
184 self.log = log
185
186 self.CreateGrid(10, 3)
187
188 # Somebody changed the grid so the type registry takes precedence
189 # over the default attribute set for editors and renderers, so we
190 # have to set null handlers for the type registry before the
191 # default editor will get used otherwise...
192 #self.RegisterDataType(wxGRID_VALUE_STRING, None, None)
193 #self.SetDefaultEditor(MyCellEditor(self.log))
194
195 # Or we could just do it like this:
196 #self.RegisterDataType(wxGRID_VALUE_STRING,
197 # wxGridCellStringRenderer(),
198 # MyCellEditor(self.log))
199
200 # but for this example, we'll just set the custom editor on one cell
201 self.SetCellEditor(1, 0, MyCellEditor(self.log))
202 self.SetCellValue(1, 0, "Try to edit this box")
203
204 # and on a column
205 attr = wxGridCellAttr()
206 attr.SetEditor(MyCellEditor(self.log))
207 self.SetColAttr(2, attr)
208 self.SetCellValue(1, 2, "or any in this column")
209
210 self.SetColSize(0, 150)
211 self.SetColSize(1, 150)
212 self.SetColSize(2, 150)
213
214
215 #---------------------------------------------------------------------------
216
217 class TestFrame(wxFrame):
218 def __init__(self, parent, log):
219 wxFrame.__init__(self, parent, -1, "Custom Grid Cell Editor Test",
220 size=(640,480))
221 grid = GridEditorTest(self, log)
222
223 #---------------------------------------------------------------------------
224
225 if __name__ == '__main__':
226 import sys
227 app = wxPySimpleApp()
228 frame = TestFrame(None, sys.stdout)
229 frame.Show(true)
230 app.MainLoop()
231
232