controls/TextCtrlAutoComplete.py
changeset 1735 c02818d7e29f
parent 1733 dea107dce0c4
child 1736 7e61baa047f0
equal deleted inserted replaced
1734:750eeb7230a1 1735:c02818d7e29f
    33 else:
    33 else:
    34     LISTBOX_BORDER_HEIGHT = 4
    34     LISTBOX_BORDER_HEIGHT = 4
    35     LISTBOX_INTERVAL_HEIGHT = 6
    35     LISTBOX_INTERVAL_HEIGHT = 6
    36 
    36 
    37 class PopupWithListbox(wx.PopupWindow):
    37 class PopupWithListbox(wx.PopupWindow):
    38     
    38 
    39     def __init__(self, parent, choices=[]):
    39     def __init__(self, parent, choices=[]):
    40         wx.PopupWindow.__init__(self, parent, wx.BORDER_SIMPLE)
    40         wx.PopupWindow.__init__(self, parent, wx.BORDER_SIMPLE)
    41         
    41 
    42         self.ListBox = wx.ListBox(self, -1, style=wx.LB_HSCROLL|wx.LB_SINGLE|wx.LB_SORT)
    42         self.ListBox = wx.ListBox(self, -1, style=wx.LB_HSCROLL|wx.LB_SINGLE|wx.LB_SORT)
    43         
    43 
    44         self.SetChoices(choices)
    44         self.SetChoices(choices)
    45         
    45 
    46         self.ListBox.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    46         self.ListBox.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    47         self.ListBox.Bind(wx.EVT_MOTION, self.OnMotion)
    47         self.ListBox.Bind(wx.EVT_MOTION, self.OnMotion)
    48     
    48 
    49     def SetChoices(self, choices):
    49     def SetChoices(self, choices):
    50         max_text_width = 0
    50         max_text_width = 0
    51         max_text_height = 0
    51         max_text_height = 0
    52         
    52 
    53         self.ListBox.Clear()
    53         self.ListBox.Clear()
    54         for choice in choices:
    54         for choice in choices:
    55             self.ListBox.Append(choice)
    55             self.ListBox.Append(choice)
    56             w, h = self.ListBox.GetTextExtent(choice)
    56             w, h = self.ListBox.GetTextExtent(choice)
    57             max_text_width = max(max_text_width, w)
    57             max_text_width = max(max_text_width, w)
    58             max_text_height = max(max_text_height, h)
    58             max_text_height = max(max_text_height, h)
    59         
    59 
    60         itemcount = min(len(choices), MAX_ITEM_SHOWN)
    60         itemcount = min(len(choices), MAX_ITEM_SHOWN)
    61         width = self.Parent.GetSize()[0]
    61         width = self.Parent.GetSize()[0]
    62         height = max_text_height * itemcount + \
    62         height = max_text_height * itemcount + \
    63                  LISTBOX_INTERVAL_HEIGHT * max(0, itemcount - 1) + \
    63                  LISTBOX_INTERVAL_HEIGHT * max(0, itemcount - 1) + \
    64                  2 * LISTBOX_BORDER_HEIGHT
    64                  2 * LISTBOX_BORDER_HEIGHT
    67         size = wx.Size(width, height)
    67         size = wx.Size(width, height)
    68         if wx.Platform == '__WXMSW__':
    68         if wx.Platform == '__WXMSW__':
    69             size.width -= 2
    69             size.width -= 2
    70         self.ListBox.SetSize(size)
    70         self.ListBox.SetSize(size)
    71         self.SetClientSize(size)
    71         self.SetClientSize(size)
    72     
    72 
    73     def MoveSelection(self, direction):
    73     def MoveSelection(self, direction):
    74         selected = self.ListBox.GetSelection()
    74         selected = self.ListBox.GetSelection()
    75         if selected == wx.NOT_FOUND:
    75         if selected == wx.NOT_FOUND:
    76             if direction >= 0:
    76             if direction >= 0:
    77                 selected = 0
    77                 selected = 0
    80         else:
    80         else:
    81             selected = (selected + direction) % (self.ListBox.GetCount() + 1)
    81             selected = (selected + direction) % (self.ListBox.GetCount() + 1)
    82         if selected == self.ListBox.GetCount():
    82         if selected == self.ListBox.GetCount():
    83             selected = wx.NOT_FOUND
    83             selected = wx.NOT_FOUND
    84         self.ListBox.SetSelection(selected)
    84         self.ListBox.SetSelection(selected)
    85     
    85 
    86     def GetSelection(self):
    86     def GetSelection(self):
    87         return self.ListBox.GetStringSelection()
    87         return self.ListBox.GetStringSelection()
    88     
    88 
    89     def OnLeftDown(self, event):
    89     def OnLeftDown(self, event):
    90         selected = self.ListBox.HitTest(wx.Point(event.GetX(), event.GetY()))
    90         selected = self.ListBox.HitTest(wx.Point(event.GetX(), event.GetY()))
    91         parent_size = self.Parent.GetSize()
    91         parent_size = self.Parent.GetSize()
    92         parent_rect = wx.Rect(0, -parent_size[1], parent_size[0], parent_size[1])
    92         parent_rect = wx.Rect(0, -parent_size[1], parent_size[0], parent_size[1])
    93         if selected != wx.NOT_FOUND:
    93         if selected != wx.NOT_FOUND:
    97             if result != wx.TE_HT_UNKNOWN:
    97             if result != wx.TE_HT_UNKNOWN:
    98                 self.Parent.SetInsertionPoint(self.Parent.XYToPosition(x, y))
    98                 self.Parent.SetInsertionPoint(self.Parent.XYToPosition(x, y))
    99         else:
    99         else:
   100             wx.CallAfter(self.Parent.DismissListBox)
   100             wx.CallAfter(self.Parent.DismissListBox)
   101         event.Skip()
   101         event.Skip()
   102     
   102 
   103     def OnMotion(self, event):
   103     def OnMotion(self, event):
   104         self.ListBox.SetSelection(
   104         self.ListBox.SetSelection(
   105             self.ListBox.HitTest(wx.Point(event.GetX(), event.GetY())))
   105             self.ListBox.HitTest(wx.Point(event.GetX(), event.GetY())))
   106         event.Skip()
   106         event.Skip()
   107     
   107 
   108 class TextCtrlAutoComplete(wx.TextCtrl):
   108 class TextCtrlAutoComplete(wx.TextCtrl):
   109 
   109 
   110     def __init__ (self, parent, choices=None, dropDownClick=True,
   110     def __init__ (self, parent, choices=None, dropDownClick=True,
   111                   element_path=None, **therest):
   111                   element_path=None, **therest):
   112         """
   112         """
   116         """
   116         """
   117 
   117 
   118         therest['style'] = wx.TE_PROCESS_ENTER | therest.get('style', 0)
   118         therest['style'] = wx.TE_PROCESS_ENTER | therest.get('style', 0)
   119 
   119 
   120         wx.TextCtrl.__init__(self, parent, **therest)
   120         wx.TextCtrl.__init__(self, parent, **therest)
   121         
   121 
   122         # Some variables
   122         # Some variables
   123         self._dropDownClick = dropDownClick
   123         self._dropDownClick = dropDownClick
   124         self._lastinsertionpoint = None
   124         self._lastinsertionpoint = None
   125         self._hasfocus = False
   125         self._hasfocus = False
   126         
   126 
   127         self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
   127         self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
   128         self.element_path = element_path
   128         self.element_path = element_path
   129         
   129 
   130         self.listbox = None
   130         self.listbox = None
   131         
   131 
   132         self.SetChoices(choices)
   132         self.SetChoices(choices)
   133 
   133 
   134         #gp = self
   134         #gp = self
   135         #while ( gp != None ) :
   135         #while ( gp != None ) :
   136         #    gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp )
   136         #    gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp )
   199             config.Flush()
   199             config.Flush()
   200             self.SetChoices(listentries)
   200             self.SetChoices(listentries)
   201         self.DismissListBox()
   201         self.DismissListBox()
   202         self._hasfocus = False
   202         self._hasfocus = False
   203         event.Skip()
   203         event.Skip()
   204     
   204 
   205     def SetChoices(self, choices):
   205     def SetChoices(self, choices):
   206         self._choices = choices
   206         self._choices = choices
   207         self.RefreshListBoxChoices()
   207         self.RefreshListBoxChoices()
   208         
   208 
   209     def GetChoices(self):
   209     def GetChoices(self):
   210         return self._choices
   210         return self._choices
   211     
   211 
   212     def SetValueFromSelected(self, selected):
   212     def SetValueFromSelected(self, selected):
   213         """
   213         """
   214         Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
   214         Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
   215         Will do nothing if no item is selected in the wx.ListCtrl.
   215         Will do nothing if no item is selected in the wx.ListCtrl.
   216         """
   216         """
   217         if selected != "":
   217         if selected != "":
   218             self.SetValue(selected)
   218             self.SetValue(selected)
   219         self.DismissListBox()
   219         self.DismissListBox()
   220     
   220 
   221     def RefreshListBoxChoices(self):
   221     def RefreshListBoxChoices(self):
   222         if self.listbox is not None:
   222         if self.listbox is not None:
   223             text = self.GetValue()
   223             text = self.GetValue()
   224             choices = [choice for choice in self._choices if choice.startswith(text)]
   224             choices = [choice for choice in self._choices if choice.startswith(text)]
   225             self.listbox.SetChoices(choices)
   225             self.listbox.SetChoices(choices)
   226 
   226 
   227     def PopupListBox(self):
   227     def PopupListBox(self):
   228         if self.listbox is None:
   228         if self.listbox is None:
   229             self.listbox = PopupWithListbox(self)
   229             self.listbox = PopupWithListbox(self)
   230             
   230 
   231             # Show the popup right below or above the button
   231             # Show the popup right below or above the button
   232             # depending on available screen space...
   232             # depending on available screen space...
   233             pos = self.ClientToScreen((0, 0))
   233             pos = self.ClientToScreen((0, 0))
   234             sz = self.GetSize()
   234             sz = self.GetSize()
   235             if wx.Platform == '__WXMSW__':
   235             if wx.Platform == '__WXMSW__':
   236                 pos.x -= 2
   236                 pos.x -= 2
   237                 pos.y -= 2
   237                 pos.y -= 2
   238             self.listbox.Position(pos, (0, sz[1]))
   238             self.listbox.Position(pos, (0, sz[1]))
   239             
   239 
   240             self.RefreshListBoxChoices()
   240             self.RefreshListBoxChoices()
   241             
   241 
   242             self.listbox.Show()
   242             self.listbox.Show()
   243 
   243 
   244     def DismissListBox(self):
   244     def DismissListBox(self):
   245         if self.listbox is not None:
   245         if self.listbox is not None:
   246             if self.listbox.ListBox.HasCapture():
   246             if self.listbox.ListBox.HasCapture():