1#!/usr/bin/env python
2
3import wx
4import wx.grid as gridlib
5#import wx.lib.mixins.grid as mixins
6
7#---------------------------------------------------------------------------
8
9class SimpleGrid(gridlib.Grid): ##, mixins.GridAutoEditMixin):
10    def __init__(self, parent, log):
11        gridlib.Grid.__init__(self, parent, -1)
12        ##mixins.GridAutoEditMixin.__init__(self)
13        self.log = log
14        self.moveTo = None
15
16        self.Bind(wx.EVT_IDLE, self.OnIdle)
17
18        self.CreateGrid(25, 25)#, gridlib.Grid.SelectRows)
19        ##self.EnableEditing(False)
20
21        # simple cell formatting
22        self.SetColSize(3, 200)
23        self.SetRowSize(4, 45)
24        self.SetCellValue(0, 0, "First cell")
25        self.SetCellValue(1, 1, "Another cell")
26        self.SetCellValue(2, 2, "Yet another cell")
27        self.SetCellValue(3, 3, "This cell is read-only")
28        self.SetCellFont(0, 0, wx.Font(12, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL))
29        self.SetCellTextColour(1, 1, wx.RED)
30        self.SetCellBackgroundColour(2, 2, wx.CYAN)
31        self.SetReadOnly(3, 3, True)
32
33        self.SetCellEditor(5, 0, gridlib.GridCellNumberEditor(1,1000))
34        self.SetCellValue(5, 0, "123")
35        self.SetCellEditor(6, 0, gridlib.GridCellFloatEditor())
36        self.SetCellValue(6, 0, "123.34")
37        self.SetCellEditor(7, 0, gridlib.GridCellNumberEditor())
38
39        self.SetCellValue(6, 3, "You can veto editing this cell")
40
41        #self.SetRowLabelSize(0)
42        #self.SetColLabelSize(0)
43
44        # attribute objects let you keep a set of formatting values
45        # in one spot, and reuse them if needed
46        attr = gridlib.GridCellAttr()
47        attr.SetTextColour(wx.BLACK)
48        attr.SetBackgroundColour(wx.RED)
49        attr.SetFont(wx.Font(10, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
50
51        # you can set cell attributes for the whole row (or column)
52        self.SetRowAttr(5, attr)
53
54        self.SetColLabelValue(0, "Custom")
55        self.SetColLabelValue(1, "column")
56        self.SetColLabelValue(2, "labels")
57
58        self.SetColLabelAlignment(wx.ALIGN_LEFT, wx.ALIGN_BOTTOM)
59
60        #self.SetDefaultCellOverflow(False)
61        #r = gridlib.GridCellAutoWrapStringRenderer()
62        #self.SetCellRenderer(9, 1, r)
63
64        # overflow cells
65        self.SetCellValue( 9, 1, "This default cell will overflow into neighboring cells, but not if you turn overflow off.");
66        self.SetCellSize(11, 1, 3, 3);
67        self.SetCellAlignment(11, 1, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE);
68        self.SetCellValue(11, 1, "This cell is set to span 3 rows and 3 columns");
69
70
71        editor = gridlib.GridCellTextEditor()
72        editor.SetParameters('10')
73        self.SetCellEditor(0, 4, editor)
74        self.SetCellValue(0, 4, "Limited text")
75
76        renderer = gridlib.GridCellAutoWrapStringRenderer()
77        self.SetCellRenderer(15,0, renderer)
78        self.SetCellValue(15,0, "The text in this cell will be rendered with word-wrapping")
79
80
81        # test all the events
82        self.Bind(gridlib.EVT_GRID_CELL_LEFT_CLICK, self.OnCellLeftClick)
83        self.Bind(gridlib.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick)
84        self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.OnCellLeftDClick)
85        self.Bind(gridlib.EVT_GRID_CELL_RIGHT_DCLICK, self.OnCellRightDClick)
86
87        self.Bind(gridlib.EVT_GRID_LABEL_LEFT_CLICK, self.OnLabelLeftClick)
88        self.Bind(gridlib.EVT_GRID_LABEL_RIGHT_CLICK, self.OnLabelRightClick)
89        self.Bind(gridlib.EVT_GRID_LABEL_LEFT_DCLICK, self.OnLabelLeftDClick)
90        self.Bind(gridlib.EVT_GRID_LABEL_RIGHT_DCLICK, self.OnLabelRightDClick)
91
92        self.Bind(gridlib.EVT_GRID_COL_SORT, self.OnGridColSort)
93
94        self.Bind(gridlib.EVT_GRID_ROW_SIZE, self.OnRowSize)
95        self.Bind(gridlib.EVT_GRID_COL_SIZE, self.OnColSize)
96
97        self.Bind(gridlib.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
98        self.Bind(gridlib.EVT_GRID_CELL_CHANGED, self.OnCellChange)
99        self.Bind(gridlib.EVT_GRID_SELECT_CELL, self.OnSelectCell)
100
101        self.Bind(gridlib.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown)
102        self.Bind(gridlib.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden)
103        self.Bind(gridlib.EVT_GRID_EDITOR_CREATED, self.OnEditorCreated)
104
105
106    def OnCellLeftClick(self, evt):
107        self.log.write("OnCellLeftClick: (%d,%d) %s\n" %
108                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
109        evt.Skip()
110
111    def OnCellRightClick(self, evt):
112        self.log.write("OnCellRightClick: (%d,%d) %s\n" %
113                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
114        evt.Skip()
115
116    def OnCellLeftDClick(self, evt):
117        self.log.write("OnCellLeftDClick: (%d,%d) %s\n" %
118                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
119        evt.Skip()
120
121    def OnCellRightDClick(self, evt):
122        self.log.write("OnCellRightDClick: (%d,%d) %s\n" %
123                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
124        evt.Skip()
125
126    def OnLabelLeftClick(self, evt):
127        self.log.write("OnLabelLeftClick: (%d,%d) %s\n" %
128                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
129        evt.Skip()
130
131    def OnLabelRightClick(self, evt):
132        self.log.write("OnLabelRightClick: (%d,%d) %s\n" %
133                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
134        evt.Skip()
135
136    def OnLabelLeftDClick(self, evt):
137        self.log.write("OnLabelLeftDClick: (%d,%d) %s\n" %
138                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
139        evt.Skip()
140
141    def OnLabelRightDClick(self, evt):
142        self.log.write("OnLabelRightDClick: (%d,%d) %s\n" %
143                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
144        evt.Skip()
145
146    def OnGridColSort(self, evt):
147        self.log.write("OnGridColSort: %s %s" % (evt.GetCol(), self.GetSortingColumn()))
148        self.SetSortingColumn(evt.GetCol())
149
150    def OnRowSize(self, evt):
151        self.log.write("OnRowSize: row %d, %s\n" %
152                       (evt.GetRowOrCol(), evt.GetPosition()))
153        evt.Skip()
154
155    def OnColSize(self, evt):
156        self.log.write("OnColSize: col %d, %s\n" %
157                       (evt.GetRowOrCol(), evt.GetPosition()))
158        evt.Skip()
159
160    def OnRangeSelect(self, evt):
161        if evt.Selecting():
162            msg = 'Selected'
163        else:
164            msg = 'Deselected'
165        self.log.write("OnRangeSelect: %s  top-left %s, bottom-right %s\n" %
166                           (msg, evt.GetTopLeftCoords(), evt.GetBottomRightCoords()))
167        evt.Skip()
168
169
170    def OnCellChange(self, evt):
171        self.log.write("OnCellChange: (%d,%d) %s\n" %
172                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
173
174        # Show how to stay in a cell that has bad data.  We can't just
175        # call SetGridCursor here since we are nested inside one so it
176        # won't have any effect.  Instead, set coordinates to move to in
177        # idle time.
178        value = self.GetCellValue(evt.GetRow(), evt.GetCol())
179
180        if value == 'no good':
181            self.moveTo = evt.GetRow(), evt.GetCol()
182
183
184    def OnIdle(self, evt):
185        if self.moveTo != None:
186            self.SetGridCursor(self.moveTo[0], self.moveTo[1])
187            self.moveTo = None
188
189        evt.Skip()
190
191
192    def OnSelectCell(self, evt):
193        if evt.Selecting():
194            msg = 'Selected'
195        else:
196            msg = 'Deselected'
197        self.log.write("OnSelectCell: %s (%d,%d) %s\n" %
198                       (msg, evt.GetRow(), evt.GetCol(), evt.GetPosition()))
199
200        # Another way to stay in a cell that has a bad value...
201        row = self.GetGridCursorRow()
202        col = self.GetGridCursorCol()
203
204        if self.IsCellEditControlEnabled():
205            self.HideCellEditControl()
206            self.DisableCellEditControl()
207
208        value = self.GetCellValue(row, col)
209
210        if value == 'no good 2':
211            return  # cancels the cell selection
212
213        evt.Skip()
214
215
216    def OnEditorShown(self, evt):
217        if evt.GetRow() == 6 and evt.GetCol() == 3 and \
218           wx.MessageBox("Are you sure you wish to edit this cell?",
219                        "Checking", wx.YES_NO) == wx.NO:
220            evt.Veto()
221            return
222
223        self.log.write("OnEditorShown: (%d,%d) %s\n" %
224                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
225        evt.Skip()
226
227
228    def OnEditorHidden(self, evt):
229        if evt.GetRow() == 6 and evt.GetCol() == 3 and \
230           wx.MessageBox("Are you sure you wish to  finish editing this cell?",
231                        "Checking", wx.YES_NO) == wx.NO:
232            evt.Veto()
233            return
234
235        self.log.write("OnEditorHidden: (%d,%d) %s\n" %
236                       (evt.GetRow(), evt.GetCol(), evt.GetPosition()))
237        evt.Skip()
238
239
240    def OnEditorCreated(self, evt):
241        self.log.write("OnEditorCreated: (%d, %d) %s\n" %
242                       (evt.GetRow(), evt.GetCol(), evt.GetControl()))
243
244
245
246#---------------------------------------------------------------------------
247
248class TestFrame(wx.Frame):
249    def __init__(self, parent, log):
250        wx.Frame.__init__(self, parent, -1, "Simple Grid Demo", size=(640,480))
251        self.grid = SimpleGrid(self, log)
252
253
254
255#---------------------------------------------------------------------------
256
257if __name__ == '__main__':
258    import sys
259    from wx.lib.mixins.inspection import InspectableApp
260    app = InspectableApp(False)
261    frame = TestFrame(None, sys.stdout)
262    frame.Show(True)
263    #import wx.lib.inspection
264    #wx.lib.inspection.InspectionTool().Show()
265    app.MainLoop()
266
267
268#---------------------------------------------------------------------------
269
270
271