| 1 | |
| 2 | import wx |
| 3 | |
| 4 | #--------------------------------------------------------------------------- |
| 5 | |
| 6 | # This listbox subclass lets you type the starting letters of what you want to |
| 7 | # select, and scrolls the list to the match if it is found. |
| 8 | class FindPrefixListBox(wx.ListBox): |
| 9 | def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, |
| 10 | choices=[], style=0, validator=wx.DefaultValidator): |
| 11 | wx.ListBox.__init__(self, parent, id, pos, size, choices, style, validator) |
| 12 | self.typedText = '' |
| 13 | self.log = parent.log |
| 14 | self.Bind(wx.EVT_KEY_DOWN, self.OnKey) |
| 15 | |
| 16 | |
| 17 | def FindPrefix(self, prefix): |
| 18 | self.log.WriteText('Looking for prefix: %s\n' % prefix) |
| 19 | |
| 20 | if prefix: |
| 21 | prefix = prefix.lower() |
| 22 | length = len(prefix) |
| 23 | |
| 24 | # Changed in 2.5 because ListBox.Number() is no longer supported. |
| 25 | # ListBox.GetCount() is now the appropriate way to go. |
| 26 | for x in range(self.GetCount()): |
| 27 | text = self.GetString(x) |
| 28 | text = text.lower() |
| 29 | |
| 30 | if text[:length] == prefix: |
| 31 | self.log.WriteText('Prefix %s is found.\n' % prefix) |
| 32 | return x |
| 33 | |
| 34 | self.log.WriteText('Prefix %s is not found.\n' % prefix) |
| 35 | return -1 |
| 36 | |
| 37 | |
| 38 | def OnKey(self, evt): |
| 39 | key = evt.GetKeyCode() |
| 40 | |
| 41 | if key >= 32 and key <= 127: |
| 42 | self.typedText = self.typedText + chr(key) |
| 43 | item = self.FindPrefix(self.typedText) |
| 44 | |
| 45 | if item != -1: |
| 46 | self.SetSelection(item) |
| 47 | |
| 48 | elif key == wx.WXK_BACK: # backspace removes one character and backs up |
| 49 | self.typedText = self.typedText[:-1] |
| 50 | |
| 51 | if not self.typedText: |
| 52 | self.SetSelection(0) |
| 53 | else: |
| 54 | item = self.FindPrefix(self.typedText) |
| 55 | |
| 56 | if item != -1: |
| 57 | self.SetSelection(item) |
| 58 | else: |
| 59 | self.typedText = '' |
| 60 | evt.Skip() |
| 61 | |
| 62 | def OnKeyDown(self, evt): |
| 63 | pass |
| 64 | |
| 65 | |
| 66 | #--------------------------------------------------------------------------- |
| 67 | |
| 68 | class TestListBox(wx.Panel): |
| 69 | def __init__(self, parent, log): |
| 70 | self.log = log |
| 71 | wx.Panel.__init__(self, parent, -1) |
| 72 | |
| 73 | sampleList = ['zero', 'one', 'two', 'three', 'four', 'five', |
| 74 | 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', |
| 75 | 'twelve', 'thirteen', 'fourteen'] |
| 76 | |
| 77 | wx.StaticText(self, -1, "This example uses the wx.ListBox control.", (45, 10)) |
| 78 | wx.StaticText(self, -1, "Select one:", (15, 50)) |
| 79 | self.lb1 = wx.ListBox(self, 60, (100, 50), (90, 120), sampleList, wx.LB_SINGLE) |
| 80 | self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.lb1) |
| 81 | self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.lb1) |
| 82 | self.lb1.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton) |
| 83 | self.lb1.SetSelection(3) |
| 84 | self.lb1.Append("with data", "This one has data"); |
| 85 | self.lb1.SetClientData(2, "This one has data"); |
| 86 | |
| 87 | |
| 88 | wx.StaticText(self, -1, "Select many:", (220, 50)) |
| 89 | self.lb2 = wx.ListBox(self, 70, (320, 50), (90, 120), sampleList, wx.LB_EXTENDED) |
| 90 | self.Bind(wx.EVT_LISTBOX, self.EvtMultiListBox, self.lb2) |
| 91 | self.lb2.Bind(wx.EVT_RIGHT_UP, self.EvtRightButton) |
| 92 | self.lb2.SetSelection(0) |
| 93 | |
| 94 | sampleList = sampleList + ['test a', 'test aa', 'test aab', |
| 95 | 'test ab', 'test abc', 'test abcc', |
| 96 | 'test abcd' ] |
| 97 | sampleList.sort() |
| 98 | wx.StaticText(self, -1, "Find Prefix:", (15, 250)) |
| 99 | fp = FindPrefixListBox(self, -1, (100, 250), (90, 120), sampleList, wx.LB_SINGLE) |
| 100 | fp.SetSelection(0) |
| 101 | |
| 102 | |
| 103 | def EvtListBox(self, event): |
| 104 | self.log.WriteText('EvtListBox: %s, %s, %s\n' % |
| 105 | (event.GetString(), event.IsSelection(), event.GetSelection())) |
| 106 | |
| 107 | lb = event.GetEventObject() |
| 108 | data = lb.GetClientData(lb.GetSelection()) |
| 109 | |
| 110 | if data is not None: |
| 111 | self.log.WriteText('\tdata: %s\n' % data) |
| 112 | |
| 113 | |
| 114 | def EvtListBoxDClick(self, event): |
| 115 | self.log.WriteText('EvtListBoxDClick: %s\n' % self.lb1.GetSelection()) |
| 116 | self.lb1.Delete(self.lb1.GetSelection()) |
| 117 | |
| 118 | def EvtMultiListBox(self, event): |
| 119 | self.log.WriteText('EvtMultiListBox: %s\n' % str(self.lb2.GetSelections())) |
| 120 | |
| 121 | def EvtRightButton(self, event): |
| 122 | self.log.WriteText('EvtRightButton: %s\n' % event.GetPosition()) |
| 123 | |
| 124 | if event.GetEventObject().GetId() == 70: |
| 125 | selections = list(self.lb2.GetSelections()) |
| 126 | selections.reverse() |
| 127 | |
| 128 | for index in selections: |
| 129 | self.lb2.Delete(index) |
| 130 | |
| 131 | |
| 132 | #--------------------------------------------------------------------------- |
| 133 | |
| 134 | def runTest(frame, nb, log): |
| 135 | win = TestListBox(nb, log) |
| 136 | return win |
| 137 | |
| 138 | #--------------------------------------------------------------------------- |
| 139 | |
| 140 | |
| 141 | |
| 142 | |
| 143 | overview = """<html><body> |
| 144 | A listbox is used to select one or more of a list of |
| 145 | strings. The strings are displayed in a scrolling box, with the |
| 146 | selected string(s) marked in reverse video. A listbox can be single |
| 147 | selection (if an item is selected, the previous selection is removed) |
| 148 | or multiple selection (clicking an item toggles the item on or off |
| 149 | independently of other selections). |
| 150 | </body></html> |
| 151 | """ |
| 152 | |
| 153 | |
| 154 | if __name__ == '__main__': |
| 155 | import sys,os |
| 156 | import run |
| 157 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) |
| 158 | |