--- a/controls/TextCtrlAutoComplete.py Tue May 28 17:52:07 2013 +0200
+++ b/controls/TextCtrlAutoComplete.py Tue May 28 17:52:57 2013 +0200
@@ -28,28 +28,23 @@
MAX_ITEM_COUNT = 10
MAX_ITEM_SHOWN = 6
if wx.Platform == '__WXMSW__':
- ITEM_INTERVAL_HEIGHT = 3
+ LISTBOX_BORDER_HEIGHT = 2
+ LISTBOX_INTERVAL_HEIGHT = 0
else:
- ITEM_INTERVAL_HEIGHT = 6
-
-if wx.Platform == '__WXMSW__':
- popupclass = wx.PopupTransientWindow
-else:
- popupclass = wx.PopupWindow
-
-class PopupWithListbox(popupclass):
+ LISTBOX_BORDER_HEIGHT = 4
+ LISTBOX_INTERVAL_HEIGHT = 6
+
+class PopupWithListbox(wx.PopupWindow):
def __init__(self, parent, choices=[]):
- popupclass.__init__(self, parent, wx.SIMPLE_BORDER)
+ wx.PopupWindow.__init__(self, parent, wx.BORDER_SIMPLE)
self.ListBox = wx.ListBox(self, -1, style=wx.LB_HSCROLL|wx.LB_SINGLE|wx.LB_SORT)
- if not wx.Platform == '__WXMSW__':
- self.ListBox.Bind(wx.EVT_LISTBOX, self.OnListBoxClick)
- self.ListBox.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListBoxClick)
-
+
self.SetChoices(choices)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+ self.ListBox.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+ self.ListBox.Bind(wx.EVT_MOTION, self.OnMotion)
def SetChoices(self, choices):
max_text_width = 0
@@ -64,10 +59,14 @@
itemcount = min(len(choices), MAX_ITEM_SHOWN)
width = self.Parent.GetSize()[0]
- height = max_text_height * itemcount + ITEM_INTERVAL_HEIGHT * (itemcount + 1)
+ height = max_text_height * itemcount + \
+ LISTBOX_INTERVAL_HEIGHT * max(0, itemcount - 1) + \
+ 2 * LISTBOX_BORDER_HEIGHT
if max_text_width + 10 > width:
height += 15
size = wx.Size(width, height)
+ if wx.Platform == '__WXMSW__':
+ size.width -= 2
self.ListBox.SetSize(size)
self.SetClientSize(size)
@@ -87,28 +86,28 @@
def GetSelection(self):
return self.ListBox.GetStringSelection()
- def ProcessLeftDown(self, event):
+ def OnLeftDown(self, event):
selected = self.ListBox.HitTest(wx.Point(event.m_x, event.m_y))
+ parent_size = self.Parent.GetSize()
+ parent_rect = wx.Rect(0, -parent_size[1], parent_size[0], parent_size[1])
if selected != wx.NOT_FOUND:
wx.CallAfter(self.Parent.SetValueFromSelected, self.ListBox.GetString(selected))
- return False
-
- def OnListBoxClick(self, event):
- selected = event.GetSelection()
- if selected != wx.NOT_FOUND:
- wx.CallAfter(self.Parent.SetValueFromSelected, self.ListBox.GetString(selected))
- event.Skip()
-
- def OnKeyDown(self, event):
- self.Parent.ProcessEvent(event)
-
- def OnDismiss(self):
- self.Parent.listbox = None
- wx.CallAfter(self.Parent.DismissListBox)
+ elif parent_rect.InsideXY(event.m_x, event.m_y):
+ result, x, y = self.Parent.HitTest(wx.Point(event.m_x, event.m_y + parent_size[1]))
+ if result != wx.TE_HT_UNKNOWN:
+ self.Parent.SetInsertionPoint(self.Parent.XYToPosition(x, y))
+ else:
+ wx.CallAfter(self.Parent.DismissListBox)
+ event.Skip()
+
+ def OnMotion(self, event):
+ self.ListBox.SetSelection(
+ self.ListBox.HitTest(wx.Point(event.m_x, event.m_y)))
+ event.Skip()
class TextCtrlAutoComplete(wx.TextCtrl):
- def __init__ (self, parent, appframe, choices=None, dropDownClick=True,
+ def __init__ (self, parent, choices=None, dropDownClick=True,
element_path=None, **therest):
"""
Constructor works just like wx.TextCtrl except you can pass in a
@@ -119,11 +118,11 @@
therest['style'] = wx.TE_PROCESS_ENTER | therest.get('style', 0)
wx.TextCtrl.__init__(self, parent, **therest)
- self.AppFrame = appframe
#Some variables
self._dropDownClick = dropDownClick
self._lastinsertionpoint = None
+ self._hasfocus = False
self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
self.element_path = element_path
@@ -148,9 +147,6 @@
self.Bind(wx.EVT_LEFT_DOWN, self.OnClickToggleDown)
self.Bind(wx.EVT_LEFT_UP, self.OnClickToggleUp)
- def __del__(self):
- self.AppFrame = None
-
def ChangeValue(self, value):
wx.TextCtrl.ChangeValue(self, value)
self.RefreshListBoxChoices()
@@ -171,7 +167,11 @@
else:
self.listbox.MoveSelection(-1)
elif keycode in [wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_RETURN] and self.listbox is not None:
- self.SetValueFromSelected(self.listbox.GetSelection())
+ selected = self.listbox.GetSelection()
+ if selected != "":
+ self.SetValueFromSelected(selected)
+ else:
+ event.Skip()
elif event.GetKeyCode() == wx.WXK_ESCAPE:
self.DismissListBox()
else:
@@ -182,7 +182,9 @@
event.Skip()
def OnClickToggleUp(self, event):
- if self.GetInsertionPoint() == self._lastinsertionpoint:
+ if not self._hasfocus:
+ self._hasfocus = True
+ elif self.GetInsertionPoint() == self._lastinsertionpoint:
wx.CallAfter(self.PopupListBox)
self._lastinsertionpoint = None
event.Skip()
@@ -197,6 +199,7 @@
config.Flush()
self.SetChoices(listentries)
self.DismissListBox()
+ self._hasfocus = False
event.Skip()
def SetChoices(self, choices):
@@ -207,13 +210,13 @@
return self._choices
def SetValueFromSelected(self, selected):
- """
- Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
- Will do nothing if no item is selected in the wx.ListCtrl.
- """
- if selected != "":
+ """
+ Sets the wx.TextCtrl value from the selected wx.ListCtrl item.
+ Will do nothing if no item is selected in the wx.ListCtrl.
+ """
+ if selected != "":
self.SetValue(selected)
- self.DismissListBox()
+ self.DismissListBox()
def RefreshListBoxChoices(self):
if self.listbox is not None:
@@ -229,22 +232,18 @@
# depending on available screen space...
pos = self.ClientToScreen((0, 0))
sz = self.GetSize()
+ if wx.Platform == '__WXMSW__':
+ pos.x -= 2
+ pos.y -= 2
self.listbox.Position(pos, (0, sz[1]))
self.RefreshListBoxChoices()
- if wx.Platform == '__WXMSW__':
- self.listbox.Popup()
- else:
- self.listbox.Show()
- self.AppFrame.EnableScrolling(False)
+ self.listbox.Show()
def DismissListBox(self):
if self.listbox is not None:
- if wx.Platform == '__WXMSW__':
- self.listbox.Dismiss()
- else:
- self.listbox.Destroy()
+ if self.listbox.ListBox.HasCapture():
+ self.listbox.ListBox.ReleaseMouse()
+ self.listbox.Destroy()
self.listbox = None
- self.AppFrame.EnableScrolling(True)
-
--- a/editors/ConfTreeNodeEditor.py Tue May 28 17:52:07 2013 +0200
+++ b/editors/ConfTreeNodeEditor.py Tue May 28 17:52:57 2013 +0200
@@ -210,11 +210,8 @@
panel_style |= wx.SUNKEN_BORDER
self.ParamsEditor = wx.ScrolledWindow(parent,
style=panel_style)
- self.ParamsEditor.Bind(wx.EVT_SIZE, self.OnWindowResize)
- self.ParamsEditor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
-
- # Variable allowing disabling of ParamsEditor scroll when Popup shown
- self.ScrollingEnabled = True
+ self.ParamsEditor.Bind(wx.EVT_SIZE, self.OnParamsEditorResize)
+ self.ParamsEditor.Bind(wx.EVT_SCROLLWIN, self.OnParamsEditorScroll)
self.ParamsEditorSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=5)
self.ParamsEditorSizer.AddGrowableCol(0)
@@ -278,9 +275,6 @@
self.RefreshConfNodeParamsSizer()
self.RefreshScrollbars()
- def EnableScrolling(self, enable):
- self.ScrollingEnabled = enable
-
def RefreshIECChannelControlsState(self):
self.FullIECChannel.SetLabel(self.Controler.GetFullIEC_Channel())
self.IECCDownButton.Enable(self.Controler.BaseParams.getIEC_Channel() > 0)
@@ -469,7 +463,6 @@
choices = self.ParentWindow.GetConfigEntry(element_path, [""])
textctrl = TextCtrlAutoComplete(name=element_infos["name"],
parent=self.ParamsEditor,
- appframe=self,
choices=choices,
element_path=element_path,
size=wx.Size(300, -1))
@@ -477,7 +470,9 @@
boxsizer.AddWindow(textctrl)
if element_infos["value"] is not None:
textctrl.ChangeValue(str(element_infos["value"]))
- textctrl.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(textctrl, element_path))
+ callback = self.GetTextCtrlCallBackFunction(textctrl, element_path)
+ textctrl.Bind(wx.EVT_TEXT_ENTER, callback)
+ textctrl.Bind(wx.EVT_KILL_FOCUS, callback)
first = False
@@ -569,11 +564,14 @@
self.ParamsEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
- def OnWindowResize(self, event):
+ def OnParamsEditorResize(self, event):
self.RefreshScrollbars()
event.Skip()
- def OnMouseWheel(self, event):
- if self.ScrollingEnabled:
- event.Skip()
-
+ def OnParamsEditorScroll(self, event):
+ control = self.ParamsEditor.FindFocus()
+ if isinstance(control, TextCtrlAutoComplete):
+ control.DismissListBox()
+ self.Refresh()
+ event.Skip()
+