Hi folks,
Another try for a Autofind Mixin class.
wx.ComboBox, wx.Choice and wx.ListCtrl (only single selection) supported.
You can try it, if you change the commented code.
Added four common function, which should work depending
on the type of the control:
def GetSelectedItem(self):
def SetSelectedItem(self, index):
def GetItemString(self, index):
def GetNrEntries(self):
Does it work on Linux?
For suggestions (of the code itself, the code style or another ideas, bugs),
I would be glad to hear.
···
========================================================================================
#!/usr/bin/env python
# Franz Steinhaeusler, 09.05.2006
# AutoFindMixin.py
import wx
class AutoFindMixin:
"""AutoFindMixin: it will search for elements which fits a whole typed in word fragment."""
def __init__(self, parent, showbuffer=False):
"""Creates the AutoFindMixin Class."""
# taken from listctrl Mixins class
self.control = control = self.GetControl()
if not control:
raise ValueError, "No Control available"
else:
if isinstance(control, wx.Choice) or \
isinstance(control, wx.ComboBox) or \
isinstance(control, wx.ListCtrl):
#print "ok", control
pass
else:
raise ValueError, "Not supported control:", control
self.keybuffer = ""
self.showbuffer = showbuffer
self.lastpos = self.GetSelectedItem()
if showbuffer:
# create a static text to show current keybuffer.
x, y = self.GetPosition()
w, h = self.GetSize()
self.StaticText = wx.StaticText(parent, pos=(x+w+5,y+3))
self.StaticText.SetBackgroundColour(wx.Colour(255, 255, 192))
# bind the contrrol
control.Bind(wx.EVT_CHAR, self.OnChar)
control.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
control.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
self.Bind(wx.EVT_CHOICE, self.OnChoice)
def GetSelectedItem(self):
"""Get index of the currently selected item."""
if isinstance(self.control, wx.ListCtrl):
return self.control.GetNextItem(-1, wx.LIST_NEXT_ALL,
wx.LIST_STATE_SELECTED)
else:
return self.control.GetSelection()
pass
def SetSelectedItem(self, index):
"""Set active item to the given index."""
if isinstance(self.control, wx.ListCtrl):
self.SetItemState(index, wx.LIST_STATE_SELECTED|wx.LIST_STATE_FOCUSED,
wx.LIST_STATE_SELECTED|wx.LIST_STATE_FOCUSED)
pass
else:
self.SetSelection(index)
pass
def GetItemString(self, index):
"""Get Currently selected item of the AutoFindMixin control."""
if isinstance(self.control, wx.ListCtrl):
return self.control.GetItem(index, 0).GetText()
else:
return self.control.GetString(index)
def GetNrEntries(self):
"""Get Number of Entries of the AutoFindMixin control."""
if isinstance(self.control, wx.ListCtrl):
return self.control.GetItemCount()
else:
return self.control.GetCount()
def OnKillFocus(self, event):
"""AutoFindMixin control loses the focus. => save the last postion of the selection."""
self.lastpos = self.GetSelectedItem()
event.Skip()
def OnSetFocus(self, event):
"""AutoFindMixin control gets the focus. => Clear the buffer."""
self.keybuffer = ""
self.ShowBuffer()
#print self.lastpos
#self.SetSelection(self.lastpos)
event.Skip()
def OnChar(self, event):
"""Process current typed in key."""
if event.GetKeyCode() > 255 or event.GetKeyCode() in (wx.WXK_RETURN, wx.WXK_TAB):
# example: cursor keys should work as expected.
# and return and tab should not fill the keybuffer list.
event.Skip()
return
if event.GetKeyCode() == wx.WXK_BACK:
# delete last key in buffer
if len (self.keybuffer) > 0:
self.keybuffer = self.keybuffer[:-1]
elif event.GetKeyCode() == wx.WXK_ESCAPE:
# delete buffer with Escape key.
self.keybuffer = ""
self.SetSelectedItem(self.lastpos)
self.ShowBuffer()
return
else:
# extend buffer with current pressed key.
self.keybuffer += chr (event.GetKeyCode())
#print self.lastpos
self.ShowBuffer()
# try to find in the list
for i in range(self.GetNrEntries()):
if self.GetItemString(i).find(self.keybuffer) == 0:
# save lastpos before first typing a char
if len(self.keybuffer) == 1 and not event.GetKeyCode() == wx.WXK_BACK:
self.lastpos = self.GetSelectedItem()
self.SetSelectedItem(i)
#print self.lastpos
return
def OnChoice(self, event):
"""This could be skipped."""
#print '1. EvtChoice: %s\n' % event.GetString(),
self.lastpos = self.GetSelectedItem()
#print self.lastpos
event.Skip()
def ShowBuffer(self):
"""Display Key Buffer."""
if self.showbuffer:
if self.keybuffer == "":
self.StaticText.SetLabel("")
else:
self.StaticText.SetLabel("'" + self.keybuffer + "'")
========================================================================================
#!/usr/bin/env python
# Franz Steinhaeusler, 09.05.2006
# TestAutoFind.py Demo Application
import wx
from AutoFindMixin import AutoFindMixin
class ChoiceAutoFind(wx.Choice, AutoFindMixin):
"""ChoiceAutoFind: Demo Sample to present the AutoFindMixin class with a wx.Choice."""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, choices=[], style=0, showbuffer=False):
"""Create the ChoiceAutoFind Control."""
wx.Choice.__init__(self, parent, id, pos, size, choices, style)
AutoFindMixin.__init__(self, parent, showbuffer)
# this class must be overwritten
def GetControl(self):
"""returns the assigned control."""
return self
class ComboBoxAutoFind(wx.ComboBox, AutoFindMixin):
"""ComboBoxAutoFind: Demo Sample to present the AutoFindMixin class with a wx.ComboBox."""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, choices=[], style=0, showbuffer=False):
"""Create the ComboBoxAutoFind Control."""
wx.ComboBox.__init__(self, parent, id, "", pos, size, choices, style)
AutoFindMixin.__init__(self, parent, showbuffer)
# this class must be overwritten
def GetControl(self):
"""returns the assigned control."""
return self
class ListCtrlAutoFind(wx.ListCtrl, AutoFindMixin):
"""ListCtrlAutoFind: Demo Sample to present the AutoFindMixin class with a wx.ListCtrl."""
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
size=wx.DefaultSize, choices=[], style=0, showbuffer=False):
"""Create the ListCtrlAutoFind Control."""
wx.ListCtrl.__init__(self, parent, pos=pos, size=size, style=wx.LC_REPORT|wx.LC_SINGLE_SEL)
self.InsertColumn(0, "Col1")
self.InsertColumn(1, "Col2")
listindex = 0
for c in choices:
self.InsertStringItem(listindex, c)
self.SetStringItem(listindex, 1, "line1%d" % listindex)
listindex += 1
self.SetSize ((150, 150))
AutoFindMixin.__init__(self, parent, showbuffer)
# this class must be overwritten
def GetControl(self):
"""returns the assigned control."""
return self
class TestAutoFindPanel(wx.Panel):
"""Test Panel for AutoFind."""
def __init__(self, parent, showbuffer=False):
"""Create the TestAutoFind Panel."""
wx.Panel.__init__(self, parent, -1)
wx.StaticText(self, -1, "Select one:", pos=(15, 10), size=(75, -1))
sampleList = ['zero', 'one', 'two', 'three', 'thirteen', 'twenty']
wx.StaticText(self, -1, "TextCtrl:", pos=(15, 180), size=(75, -1))
txt = wx.TextCtrl(self, pos=(100,180))
#self.ch = ChoiceAutoFind(self, pos=(100, 10), choices=sampleList, showbuffer=showbuffer)
#self.ch = ComboBoxAutoFind(self, pos=(100, 10), choices=sampleList, showbuffer=showbuffer)
self.ch = ListCtrlAutoFind(self, pos=(100, 10), choices=sampleList, showbuffer=showbuffer)
self.ch.SetFocus()
self.ch.Bind(wx.EVT_CHOICE, self.OnChoice)
def OnChoice(self, event):
"""Display currently selected entry.."""
#print '2. EvtChoice: %s\n' % event.GetString()
event.Skip()
if __name__ == "__main__":
app = wx.App(0)
frame = wx.Frame(None, title="Test Auto Find App", size=(350, 300))
frame.Center()
#TestAutoFindPanel(frame)
TestAutoFindPanel(frame, showbuffer=True)
frame.Show()
app.MainLoop()
--
Franz Steinhaeusler