]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/wxListCtrl.py
focus setting must be possible even when not shown yet
[wxWidgets.git] / wxPython / demo / wxListCtrl.py
CommitLineData
cf694132
RD
1#----------------------------------------------------------------------------
2# Name: ListCtrl.py
3# Purpose: Testing lots of stuff, controls, window types, etc.
4#
5# Author: Robin Dunn & Gary Dumer
6#
7# Created:
8# RCS-ID: $Id$
9# Copyright: (c) 1998 by Total Control Software
10# Licence: wxWindows license
11#----------------------------------------------------------------------------
12
13from wxPython.wx import *
726fc00a 14from wxPython.lib.mixins.listctrl import wxColumnSorterMixin, wxListCtrlAutoWidthMixin
cf694132
RD
15
16#---------------------------------------------------------------------------
17
dcd38683
RD
18musicdata = {
191 : ("Bad English", "The Price Of Love", "Rock"),
202 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
213 : ("George Michael", "Praying For Time", "Rock"),
224 : ("Gloria Estefan", "Here We Are", "Rock"),
235 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
246 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
cd096152
RD
257 : ("Paul Young", "Oh Girl", "Rock"),
268 : ("Paula Abdul", "Opposites Attract", "Rock"),
279 : ("Richard Marx", "Should've Known Better", "Rock"),
2810: ("Rod Stewart", "Forever Young", "Rock"),
2911: ("Roxette", "Dangerous", "Rock"),
3012: ("Sheena Easton", "The Lover In Me", "Rock"),
3113: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
3214: ("Stevie B.", "Because I Love You", "Rock"),
3315: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
3416: ("The Bangles", "Eternal Flame", "Rock"),
3517: ("Wilson Phillips", "Release Me", "Rock"),
3618: ("Billy Joel", "Blonde Over Blue", "Rock"),
3719: ("Billy Joel", "Famous Last Words", "Rock"),
3820: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
3921: ("Billy Joel", "The River Of Dreams", "Rock"),
4022: ("Billy Joel", "Two Thousand Years", "Rock"),
4123: ("Janet Jackson", "Alright", "Rock"),
4224: ("Janet Jackson", "Black Cat", "Rock"),
4325: ("Janet Jackson", "Come Back To Me", "Rock"),
4426: ("Janet Jackson", "Escapade", "Rock"),
4527: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
4628: ("Janet Jackson", "Miss You Much", "Rock"),
4729: ("Janet Jackson", "Rhythm Nation", "Rock"),
4830: ("Janet Jackson", "State Of The World", "Rock"),
4931: ("Janet Jackson", "The Knowledge", "Rock"),
5032: ("Spyro Gyra", "End of Romanticism", "Jazz"),
5133: ("Spyro Gyra", "Heliopolis", "Jazz"),
5234: ("Spyro Gyra", "Jubilee", "Jazz"),
5335: ("Spyro Gyra", "Little Linda", "Jazz"),
5436: ("Spyro Gyra", "Morning Dance", "Jazz"),
5537: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
5638: ("Yes", "Owner Of A Lonely Heart", "Rock"),
5739: ("Yes", "Rhythm Of Love", "Rock"),
b1cfebd9
RD
5840: ("Cusco", "Dream Catcher", "New Age"),
5941: ("Cusco", "Geronimos Laughter", "New Age"),
6042: ("Cusco", "Ghost Dance", "New Age"),
6143: ("Blue Man Group", "Drumbone", "New Age"),
6244: ("Blue Man Group", "Endless Column", "New Age"),
6345: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
6446: ("Kenny G", "Silhouette", "Jazz"),
6547: ("Sade", "Smooth Operator", "Jazz"),
6648: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)", "New Age"),
6749: ("David Arkenstone", "Stepping Stars", "New Age"),
6850: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
6951: ("David Lanz", "Behind The Waterfall", "New Age"),
7052: ("David Lanz", "Cristofori's Dream", "New Age"),
7153: ("David Lanz", "Heartsounds", "New Age"),
7254: ("David Lanz", "Leaves on the Seine", "New Age"),
dcd38683
RD
73}
74
96bfd053 75import images
dcd38683 76
726fc00a
RD
77
78class TestListCtrl(wxListCtrl, wxListCtrlAutoWidthMixin):
79 def __init__(self, parent, ID, pos=wxDefaultPosition,
80 size=wxDefaultSize, style=0):
81 wxListCtrl.__init__(self, parent, ID, pos, size, style)
82 wxListCtrlAutoWidthMixin.__init__(self)
83
84
85
6d19860f 86class TestListCtrlPanel(wxPanel, wxColumnSorterMixin):
cf694132 87 def __init__(self, parent, log):
c368d904 88 wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)
cf694132
RD
89
90 self.log = log
f6bcfd97 91 tID = wxNewId()
cf694132
RD
92
93 self.il = wxImageList(16, 16)
6d19860f 94
3979290c 95 self.idx1 = self.il.Add(images.getSmilesBitmap())
00887b39
RD
96 self.sm_up = self.il.Add(images.getSmallUpArrowBitmap())
97 self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap())
98
726fc00a 99 self.list = TestListCtrl(self, tID,
1e4a197e 100 style=wxLC_REPORT | wxSUNKEN_BORDER
1fded56b 101 | wxLC_EDIT_LABELS
1e4a197e
RD
102 #| wxLC_NO_HEADER
103 #| wxLC_VRULES | wxLC_HRULES
104 )
cf694132
RD
105 self.list.SetImageList(self.il, wxIMAGE_LIST_SMALL)
106
3979290c
RD
107 self.PopulateList()
108
109 # Now that the list exists we can init the other base class,
110 # see wxPython/lib/mixins/listctrl.py
111 self.itemDataMap = musicdata
112 wxColumnSorterMixin.__init__(self, 3)
1e4a197e 113 #self.SortListItems(0, True)
3979290c
RD
114
115 EVT_SIZE(self, self.OnSize)
116 EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected)
117 EVT_LIST_ITEM_DESELECTED(self, tID, self.OnItemDeselected)
118 EVT_LIST_ITEM_ACTIVATED(self, tID, self.OnItemActivated)
119 EVT_LIST_DELETE_ITEM(self, tID, self.OnItemDelete)
120 EVT_LIST_COL_CLICK(self, tID, self.OnColClick)
121 EVT_LIST_COL_RIGHT_CLICK(self, tID, self.OnColRightClick)
122 EVT_LIST_COL_BEGIN_DRAG(self, tID, self.OnColBeginDrag)
123 EVT_LIST_COL_DRAGGING(self, tID, self.OnColDragging)
124 EVT_LIST_COL_END_DRAG(self, tID, self.OnColEndDrag)
1fded56b 125 EVT_LIST_BEGIN_LABEL_EDIT(self, tID, self.OnBeginEdit)
3979290c
RD
126
127 EVT_LEFT_DCLICK(self.list, self.OnDoubleClick)
128 EVT_RIGHT_DOWN(self.list, self.OnRightDown)
129
130 # for wxMSW
131 EVT_COMMAND_RIGHT_CLICK(self.list, tID, self.OnRightClick)
132
133 # for wxGTK
134 EVT_RIGHT_UP(self.list, self.OnRightClick)
135
cf694132 136
3979290c 137 def PopulateList(self):
6d19860f 138 if 0:
726fc00a 139 # for normal, simple columns, you can add them like this:
6d19860f
RD
140 self.list.InsertColumn(0, "Artist")
141 self.list.InsertColumn(1, "Title", wxLIST_FORMAT_RIGHT)
142 self.list.InsertColumn(2, "Genre")
143 else:
144 # but since we want images on the column header we have to do it the hard way:
145 info = wxListItem()
146 info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_FORMAT
147 info.m_image = -1
148 info.m_format = 0
149 info.m_text = "Artist"
150 self.list.InsertColumnInfo(0, info)
151
152 info.m_format = wxLIST_FORMAT_RIGHT
153 info.m_text = "Title"
154 self.list.InsertColumnInfo(1, info)
155
156 info.m_format = 0
157 info.m_text = "Genre"
158 self.list.InsertColumnInfo(2, info)
159
dcd38683
RD
160 items = musicdata.items()
161 for x in range(len(items)):
162 key, data = items[x]
3979290c 163 self.list.InsertImageStringItem(x, data[0], self.idx1)
dcd38683
RD
164 self.list.SetStringItem(x, 1, data[1])
165 self.list.SetStringItem(x, 2, data[2])
166 self.list.SetItemData(x, key)
cf694132
RD
167
168 self.list.SetColumnWidth(0, wxLIST_AUTOSIZE)
169 self.list.SetColumnWidth(1, wxLIST_AUTOSIZE)
0e947004 170 self.list.SetColumnWidth(2, 100)
cf694132 171
6d19860f 172 # show how to select an item
9416aa89 173 self.list.SetItemState(5, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED)
c368d904 174
6d19860f 175 # show how to change the colour of a couple items
c368d904
RD
176 item = self.list.GetItem(1)
177 item.SetTextColour(wxBLUE)
178 self.list.SetItem(item)
c7e7022c
RD
179 item = self.list.GetItem(4)
180 item.SetTextColour(wxRED)
181 self.list.SetItem(item)
182
bb0054cd 183 self.currentItem = 0
64be6958 184
a08cbc01 185
6d19860f
RD
186 # Used by the wxColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
187 def GetListCtrl(self):
188 return self.list
189
190 # Used by the wxColumnSorterMixin, see wxPython/lib/mixins/listctrl.py
191 def GetSortImages(self):
192 return (self.sm_dn, self.sm_up)
193
194
a08cbc01
RD
195 def OnRightDown(self, event):
196 self.x = event.GetX()
64be6958
RD
197 self.y = event.GetY()
198 self.log.WriteText("x, y = %s\n" % str((self.x, self.y)))
1e4a197e
RD
199 item, flags = self.list.HitTest((self.x, self.y))
200 if flags & wxLIST_HITTEST_ONITEM:
201 self.list.Select(item)
a08cbc01 202 event.Skip()
bb0054cd 203
185d7c3e
RD
204
205 def getColumnText(self, index, col):
206 item = self.list.GetItem(index, col)
207 return item.GetText()
208
209
bb0054cd 210 def OnItemSelected(self, event):
1e4a197e 211 ##print event.GetItem().GetTextColour()
bb0054cd 212 self.currentItem = event.m_itemIndex
9416aa89
RD
213 self.log.WriteText("OnItemSelected: %s, %s, %s, %s\n" %
214 (self.currentItem,
215 self.list.GetItemText(self.currentItem),
185d7c3e
RD
216 self.getColumnText(self.currentItem, 1),
217 self.getColumnText(self.currentItem, 2)))
9416aa89
RD
218 if self.currentItem == 10:
219 self.log.WriteText("OnItemSelected: Veto'd selection\n")
220 #event.Veto() # doesn't work
221 # this does
222 self.list.SetItemState(10, 0, wxLIST_STATE_SELECTED)
1fded56b
RD
223 event.Skip()
224
185d7c3e 225
9c2abc2c
RD
226 def OnItemDeselected(self, evt):
227 item = evt.GetItem()
1e4a197e
RD
228 self.log.WriteText("OnItemDeselected: %d" % evt.m_itemIndex)
229
230 # Show how to reselect something we don't want deselected
9c2abc2c
RD
231 if evt.m_itemIndex == 11:
232 wxCallAfter(self.list.SetItemState, 11, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED)
233
234
c368d904
RD
235 def OnItemActivated(self, event):
236 self.currentItem = event.m_itemIndex
1e4a197e
RD
237 self.log.WriteText("OnItemActivated: %s\nTopItem: %s" %
238 (self.list.GetItemText(self.currentItem), self.list.GetTopItem()))
c368d904 239
1fded56b
RD
240 def OnBeginEdit(self, event):
241 self.log.WriteText("OnBeginEdit")
242 event.Allow()
243
8bf5d46e
RD
244 def OnItemDelete(self, event):
245 self.log.WriteText("OnItemDelete\n")
246
dcd38683 247 def OnColClick(self, event):
6d19860f
RD
248 self.log.WriteText("OnColClick: %d\n" % event.GetColumn())
249
250 def OnColRightClick(self, event):
3115ef3e
RD
251 item = self.list.GetColumn(event.GetColumn())
252 self.log.WriteText("OnColRightClick: %d %s\n" %
253 (event.GetColumn(), (item.GetText(), item.GetAlign(),
254 item.GetWidth(), item.GetImage())))
dcd38683 255
6d19860f
RD
256 def OnColBeginDrag(self, event):
257 self.log.WriteText("OnColBeginDrag\n")
1192dbd4
RD
258 ## Show how to not allow a column to be resized
259 #if event.GetColumn() == 0:
260 # event.Veto()
261
c7e7022c 262
6d19860f
RD
263 def OnColDragging(self, event):
264 self.log.WriteText("OnColDragging\n")
dcd38683 265
6d19860f
RD
266 def OnColEndDrag(self, event):
267 self.log.WriteText("OnColEndDrag\n")
8bf5d46e 268
bb0054cd
RD
269 def OnDoubleClick(self, event):
270 self.log.WriteText("OnDoubleClick item %s\n" % self.list.GetItemText(self.currentItem))
185d7c3e 271 event.Skip()
a08cbc01 272
bb0054cd
RD
273 def OnRightClick(self, event):
274 self.log.WriteText("OnRightClick %s\n" % self.list.GetItemText(self.currentItem))
cce80896 275
1fded56b 276 # only do this part the first time so the events are only bound once
1e4a197e
RD
277 if not hasattr(self, "popupID1"):
278 self.popupID1 = wxNewId()
279 self.popupID2 = wxNewId()
280 self.popupID3 = wxNewId()
281 self.popupID4 = wxNewId()
282 self.popupID5 = wxNewId()
1fded56b 283 self.popupID6 = wxNewId()
1e4a197e
RD
284 EVT_MENU(self, self.popupID1, self.OnPopupOne)
285 EVT_MENU(self, self.popupID2, self.OnPopupTwo)
286 EVT_MENU(self, self.popupID3, self.OnPopupThree)
287 EVT_MENU(self, self.popupID4, self.OnPopupFour)
288 EVT_MENU(self, self.popupID5, self.OnPopupFive)
1fded56b 289 EVT_MENU(self, self.popupID6, self.OnPopupSix)
1e4a197e
RD
290
291 # make a menu
292 menu = wxMenu()
1fded56b
RD
293 # add some items
294 menu.Append(self.popupID1, "FindItem tests")
62fc0020 295 menu.Append(self.popupID2, "Iterate Selected")
1e4a197e
RD
296 menu.Append(self.popupID3, "ClearAll and repopulate")
297 menu.Append(self.popupID4, "DeleteAllItems")
298 menu.Append(self.popupID5, "GetItem")
1fded56b 299 menu.Append(self.popupID6, "Edit")
1e4a197e
RD
300
301 # Popup the menu. If an item is selected then its handler
302 # will be called before PopupMenu returns.
e166644c
RD
303 self.PopupMenu(menu, wxPoint(self.x, self.y))
304 menu.Destroy()
1e4a197e 305
a08cbc01
RD
306
307 def OnPopupOne(self, event):
308 self.log.WriteText("Popup one\n")
3b5ccda1
RD
309 print "FindItem:", self.list.FindItem(-1, "Roxette")
310 print "FindItemData:", self.list.FindItemData(-1, 11)
a08cbc01
RD
311
312 def OnPopupTwo(self, event):
62fc0020
RD
313 self.log.WriteText("Selected items:\n")
314 index = self.list.GetFirstSelected()
315 while index != -1:
316 self.log.WriteText(" %s: %s\n" % (self.list.GetItemText(index), self.getColumnText(index, 1)))
317 index = self.list.GetNextSelected(index)
318
a08cbc01
RD
319
320 def OnPopupThree(self, event):
321 self.log.WriteText("Popup three\n")
3979290c
RD
322 self.list.ClearAll()
323 wxCallAfter(self.PopulateList)
cf694132 324
8bf5d46e
RD
325 def OnPopupFour(self, event):
326 self.list.DeleteAllItems()
327
e166644c
RD
328 def OnPopupFive(self, event):
329 item = self.list.GetItem(self.currentItem)
330 print item.m_text, item.m_itemId, self.list.GetItemData(self.currentItem)
331
1fded56b
RD
332 def OnPopupSix(self, event):
333 self.list.EditLabel(self.currentItem)
334
335
cf694132
RD
336 def OnSize(self, event):
337 w,h = self.GetClientSizeTuple()
338 self.list.SetDimensions(0, 0, w, h)
339
340
341
342
a08cbc01
RD
343
344
cf694132
RD
345#---------------------------------------------------------------------------
346
347def runTest(frame, nb, log):
348 win = TestListCtrlPanel(nb, log)
349 return win
350
351#---------------------------------------------------------------------------
352
353
354
355
3115ef3e
RD
356overview = """\
357A list control presents lists in a number of formats: list view, report view, icon view and small icon view. Elements are numbered from zero.
cf694132 358
3115ef3e 359"""
cf694132
RD
360
361
362
363
364
3115ef3e
RD
365if __name__ == '__main__':
366 import sys,os
367 import run
368 run.main(['', os.path.basename(sys.argv[0])])
cf694132 369