[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r10270 - in trunk/gnue-forms: . src/uidrivers/wx/widgets
From: |
reinhard |
Subject: |
[gnue] r10270 - in trunk/gnue-forms: . src/uidrivers/wx/widgets |
Date: |
Sun, 12 Dec 2010 15:50:36 -0600 (CST) |
Author: reinhard
Date: 2010-12-12 15:50:36 -0600 (Sun, 12 Dec 2010)
New Revision: 10270
Modified:
trunk/gnue-forms/
trunk/gnue-forms/src/uidrivers/wx/widgets/entry.py
Log:
Introduced "picker" controls for numeric and date input. Now the user can
input numerical and date fields with the mouse. Helpful for applications used
with a touch pen.
Property changes on: trunk/gnue-forms
___________________________________________________________________
Name: bzr:revision-info
- timestamp: 2010-12-08 01:03:04.076999903 +0100
committer: Reinhard Müller <address@hidden>
properties:
branch-nick: forms
+ timestamp: 2010-12-11 17:52:20.673000097 +0100
committer: Reinhard Müller <address@hidden>
properties:
branch-nick: forms
Name: bzr:file-ids
- src/GFObjects/GFBlock.py
address@hidden:trunk%2Fgnue-forms:src%2FGFObjects%2FGFBlock.py
+ src/uidrivers/wx/widgets/entry.py
address@hidden:trunk%2Fgnue-forms:src%2Fuidrivers%2Fwx%2Fwidgets%2Fentry.py
Name: bzr:revision-id:v4
- 3116 address@hidden
3117 address@hidden
3118 address@hidden
3119 address@hidden
3120 address@hidden
3121 address@hidden
3122 address@hidden
3123 address@hidden
3124 address@hidden
3125 address@hidden
3126 address@hidden
3127 address@hidden
3128 address@hidden
3129 address@hidden
3130 address@hidden
3131 address@hidden
3132 address@hidden
3133 address@hidden
3134 address@hidden
3135 address@hidden
3136 address@hidden
3137 address@hidden
3138 address@hidden
3139 address@hidden
3140 address@hidden
3141 address@hidden
3142 address@hidden
3143 address@hidden
3144 address@hidden
3145 address@hidden
3146 address@hidden
3147 address@hidden
3148 address@hidden
3149 address@hidden
3150 address@hidden
3151 address@hidden
3152 address@hidden
3153 address@hidden
3154 address@hidden
3155 address@hidden
3156 address@hidden
3157 address@hidden
3158 address@hidden
3159 address@hidden
3160 address@hidden
3161 address@hidden
3162 address@hidden
3163 address@hidden
3164 address@hidden
3165 address@hidden
3166 address@hidden
3167 address@hidden
3168 address@hidden
3169 address@hidden
3170 address@hidden
3171 address@hidden
3172 address@hidden
3173 address@hidden
3174 address@hidden
3175 address@hidden
+ 3116 address@hidden
3117 address@hidden
3118 address@hidden
3119 address@hidden
3120 address@hidden
3121 address@hidden
3122 address@hidden
3123 address@hidden
3124 address@hidden
3125 address@hidden
3126 address@hidden
3127 address@hidden
3128 address@hidden
3129 address@hidden
3130 address@hidden
3131 address@hidden
3132 address@hidden
3133 address@hidden
3134 address@hidden
3135 address@hidden
3136 address@hidden
3137 address@hidden
3138 address@hidden
3139 address@hidden
3140 address@hidden
3141 address@hidden
3142 address@hidden
3143 address@hidden
3144 address@hidden
3145 address@hidden
3146 address@hidden
3147 address@hidden
3148 address@hidden
3149 address@hidden
3150 address@hidden
3151 address@hidden
3152 address@hidden
3153 address@hidden
3154 address@hidden
3155 address@hidden
3156 address@hidden
3157 address@hidden
3158 address@hidden
3159 address@hidden
3160 address@hidden
3161 address@hidden
3162 address@hidden
3163 address@hidden
3164 address@hidden
3165 address@hidden
3166 address@hidden
3167 address@hidden
3168 address@hidden
3169 address@hidden
3170 address@hidden
3171 address@hidden
3172 address@hidden
3173 address@hidden
3174 address@hidden
3175 address@hidden
3176 address@hidden
Name: bzr:text-parents
- src/GFObjects/GFBlock.py address@hidden
+ src/uidrivers/wx/widgets/entry.py address@hidden
Modified: trunk/gnue-forms/src/uidrivers/wx/widgets/entry.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/wx/widgets/entry.py 2010-12-12 21:50:33 UTC
(rev 10269)
+++ trunk/gnue-forms/src/uidrivers/wx/widgets/entry.py 2010-12-12 21:50:36 UTC
(rev 10270)
@@ -24,8 +24,10 @@
Implementation of the <entry> tag
"""
+import locale
import os
import wx
+import wx.combo
from gnue.forms.uidrivers.wx.widgets import _base
from gnue.forms.input import GFKeyMapper
@@ -85,28 +87,34 @@
def __build_default(self, parent, password=False, multiline=False):
- xFlags = wx.TE_PROCESS_TAB
+ if multiline and not self.managed:
+ self.__border = self._uiDriver.control_border('default')
- if password:
- xFlags |= wx.TE_PASSWORD
-
- if multiline:
- xFlags |= wx.TE_MULTILINE
- else:
- xFlags |= wx.TE_PROCESS_ENTER
-
- # Right-align numeric fields. This does work on wxMSW and wxGTK only.
if self._gfObject._field.datatype == 'number':
- xFlags |= wx.TE_RIGHT
+ style = wx.CB_DROPDOWN
+ ctrl = NumberEntryCtrl(parent, style=style)
- if multiline and not self.managed:
- self.__border = self._uiDriver.control_border('default')
+ elif self._gfObject._field.datatype == 'date':
+ style = wx.DP_DROPDOWN | wx.DP_ALLOWNONE
+ ctrl = DatePickerCtrl(parent, style=style)
- ctrl = wx.TextCtrl(parent, -1, style=xFlags)
+ else:
+ style = wx.TE_PROCESS_TAB
+ if password:
+ style |= wx.TE_PASSWORD
+ if multiline:
+ style |= wx.TE_MULTILINE
+ else:
+ style |= wx.TE_PROCESS_ENTER
+ ctrl = wx.TextCtrl(parent, style=style)
self.__set_size(ctrl)
- ctrl.Bind(wx.EVT_TEXT, self.__on_text_changed)
+ if isinstance(ctrl, DatePickerCtrl):
+ ctrl.Bind(wx.EVT_DATE_CHANGED, self.__on_datepicker_date_changed)
+ ctrl.Bind(wx.EVT_TEXT, self.__on_datepicker_text)
+ else:
+ ctrl.Bind(wx.EVT_TEXT, self.__on_text_changed)
ctrl.Bind(wx.EVT_CHAR, self.__on_keypress)
ctrl.Bind(wx.EVT_KEY_DOWN, self.__on_key_down)
ctrl.Bind(wx.EVT_SET_FOCUS, self.__on_set_focus)
@@ -311,6 +319,8 @@
if self.__old_background is not None:
widget.SetBackgroundColour(self.__old_background)
+ event.Skip()
+
# -------------------------------------------------------------------------
def __on_mac_choice_clicked(self, event):
@@ -345,6 +355,23 @@
# -------------------------------------------------------------------------
+ def __on_datepicker_date_changed(self, event):
+
+ widget = event.GetEventObject()
+
+ self._request('REPLACEVALUE', text=widget.GetText())
+
+ # -------------------------------------------------------------------------
+
+ def __on_datepicker_text(self, event):
+
+ widget = event.GetEventObject()
+
+ self._request('REPLACEVALUE', text=widget.GetValue(),
+ position=widget.GetInsertionPoint())
+
+ # -------------------------------------------------------------------------
+
def __on_gtk_text_changed(self, event):
# FIXME: workaround for issue-144. Setting a selection within an
@@ -406,6 +433,12 @@
event.Skip()
return
+ # Let Windows' date picker handle up/down.
+ if 'wxMSW' in wx.PlatformInfo and isinstance(control, DatePickerCtrl):
+ if keycode in (wx.WXK_UP, wx.WXK_DOWN):
+ event.Skip()
+ return
+
# Handle cursor up/down and page up/down.
if not (event.ShiftDown() or event.CmdDown() or event.AltDown()):
if keycode == wx.WXK_UP:
@@ -541,6 +574,8 @@
# with the string value (e.g. in Choice-Controls on OS X)
if not widget.SetStringSelection(value):
widget.SetValue(value)
+ elif isinstance(widget, DatePickerCtrl):
+ widget.SetText(value)
else:
widget.SetValue(value)
@@ -602,6 +637,10 @@
# Take care: SetSelection in a ListBox sets the selected item!
pass
+ elif isinstance(widget, DatePickerCtrl) and 'wxMSW' in wx.PlatformInfo:
+ # Windows' native DatePickerCtrl doesn't have a selection.
+ pass
+
elif hasattr(widget, 'SetSelection'):
if 'wxGTK' in wx.PlatformInfo:
wx.CallAfter(widget.SetSelection, selection1, selection2)
@@ -743,7 +782,9 @@
# Add border width.
# FIXME: This is only an estimate, but I haven't found out how to
# determine the real border width in wx.
- if self._gfObject.style.lower() == 'dropdown':
+ if isinstance (control, wx.ComboBox) \
+ or isinstance (control, NumberEntryCtrl) \
+ or isinstance (control, DatePickerCtrl):
min_w += 4
if max_w:
max_w += 4
@@ -826,6 +867,271 @@
# =============================================================================
+# Number Entry Control
+# =============================================================================
+
+class NumberEntryCtrl(wx.combo.ComboCtrl):
+
+ def __init__(self, *args, **kwargs):
+
+ wx.combo.ComboCtrl.__init__(self, *args, **kwargs)
+
+ popup = NumberEntryPopup()
+ popup.TextCtrl = self.GetTextCtrl()
+ self.SetPopupControl(popup)
+
+ # In wxWidgets 2.8, wxComboCtrl receives the EVT_SET_FOCUS events from
+ # the TextCtrl, but not EVT_KILL_FOCUS events. This seems to be fixed
+ # in wxWidgets 2.9, so this workaround can be removed when we require
+ # higher versions of wxWidgets.
+ self.GetTextCtrl().Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+
+ # -------------------------------------------------------------------------
+
+ def OnKillFocus(self, event):
+
+ e = event.Clone()
+ e.SetEventObject(self)
+ self.GetEventHandler().ProcessEvent(e)
+
+ event.Skip()
+
+ # -------------------------------------------------------------------------
+
+ def GetBackgroundColour(self, *args, **kwargs):
+
+ return self.GetTextCtrl().GetBackgroundColour(*args, **kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetBackgroundColour(self, *args, **kwargs):
+
+ return self.GetTextCtrl().SetBackgroundColour(*args, **kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetSelection(self, *args, **kwargs):
+
+ return self.GetTextCtrl().SetSelection(*args, **kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetInsertionPoint(self, *args, **kwargs):
+
+ return self.GetTextCtrl().SetInsertionPoint(*args, **kwargs)
+
+# =============================================================================
+
+class NumberEntryPopup(wx.combo.ComboPopup):
+
+ def Create(self, parent, *args, **kwargs):
+
+ wx.combo.ComboPopup.Create(self, parent, *args, **kwargs)
+
+ self.panel = wx.Panel(parent, style=wx.BORDER_SIMPLE)
+
+ radixc = u" " + locale.localeconv()['decimal_point'] + u" "
+
+ self.b1 = wx.Button(self.panel, label=u" 1 ", style=wx.BU_EXACTFIT)
+ self.b2 = wx.Button(self.panel, label=u" 2 ", style=wx.BU_EXACTFIT)
+ self.b3 = wx.Button(self.panel, label=u" 3 ", style=wx.BU_EXACTFIT)
+ self.b4 = wx.Button(self.panel, label=u" 4 ", style=wx.BU_EXACTFIT)
+ self.b5 = wx.Button(self.panel, label=u" 5 ", style=wx.BU_EXACTFIT)
+ self.b6 = wx.Button(self.panel, label=u" 6 ", style=wx.BU_EXACTFIT)
+ self.b7 = wx.Button(self.panel, label=u" 7 ", style=wx.BU_EXACTFIT)
+ self.b8 = wx.Button(self.panel, label=u" 8 ", style=wx.BU_EXACTFIT)
+ self.b9 = wx.Button(self.panel, label=u" 9 ", style=wx.BU_EXACTFIT)
+ self.b0 = wx.Button(self.panel, label=u" 0 ", style=wx.BU_EXACTFIT)
+ self.br = wx.Button(self.panel, label=radixc, style=wx.BU_EXACTFIT)
+ self.bx = wx.Button(self.panel, label=u" x ", style=wx.BU_EXACTFIT)
+ self.b1.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b2.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b3.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b4.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b5.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b6.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b7.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b8.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b9.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.b0.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.br.Bind(wx.EVT_BUTTON, self.OnClick)
+ self.bx.Bind(wx.EVT_BUTTON, self.OnClick)
+
+ box = wx.GridSizer(rows=4, cols=3)
+ box.Add(self.b1, flag=wx.EXPAND)
+ box.Add(self.b2, flag=wx.EXPAND)
+ box.Add(self.b3, flag=wx.EXPAND)
+ box.Add(self.b4, flag=wx.EXPAND)
+ box.Add(self.b5, flag=wx.EXPAND)
+ box.Add(self.b6, flag=wx.EXPAND)
+ box.Add(self.b7, flag=wx.EXPAND)
+ box.Add(self.b8, flag=wx.EXPAND)
+ box.Add(self.b9, flag=wx.EXPAND)
+ box.Add(self.b0, flag=wx.EXPAND)
+ box.Add(self.br, flag=wx.EXPAND)
+ box.Add(self.bx, flag=wx.EXPAND)
+ self.panel.SetSizerAndFit(box)
+
+ # -------------------------------------------------------------------------
+
+ def OnClick(self, event):
+
+ char = event.GetEventObject().GetLabel()[1:2]
+ if char == "x":
+ self.TextCtrl.ChangeValue(self.TextCtrl.GetValue()[:-1])
+ self.TextCtrl.SetInsertionPointEnd()
+ else:
+ self.TextCtrl.WriteText(char)
+
+ # -------------------------------------------------------------------------
+
+ def GetControl(self, *args, **kwds):
+
+ return self.panel
+
+ # -------------------------------------------------------------------------
+
+ def GetAdjustedSize(self, *args, **kwds):
+
+ return self.panel.GetMinSize()
+
+
+# =============================================================================
+# Date Picker Control
+# =============================================================================
+
+class DatePickerCtrl(wx.DatePickerCtrl):
+
+ def __init__(self, *args, **kwargs):
+
+ wx.DatePickerCtrl.__init__(self, *args, **kwargs)
+
+ # The native control available in Windows doesn't have all the breakage
+ # we try to fix here, so we just do nothing.
+ if 'wxMSW' in wx.PlatformInfo:
+ return
+
+ self.combo = None
+
+ for child in self.GetChildren():
+ if isinstance (child, wx.combo.ComboCtrl):
+ self.combo = child
+
+ # Make sure we receive the interesting events from the TextCtrl.
+ self.combo.GetTextCtrl().Bind(wx.EVT_KEY_DOWN, self.OnEvent)
+ self.combo.GetTextCtrl().Bind(wx.EVT_CHAR, self.OnEvent)
+ self.combo.GetTextCtrl().Bind(wx.EVT_SET_FOCUS, self.OnEvent)
+ self.combo.GetTextCtrl().Bind(wx.EVT_KILL_FOCUS, self.OnEvent)
+
+ self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
+ self.Bind(wx.EVT_TEXT, self.OnText)
+
+ self.propagating_event = False
+
+ # -------------------------------------------------------------------------
+
+ def OnEvent(self, event):
+
+ self.propagating_event = True
+ try:
+ e = event.Clone()
+ e.SetEventObject(self)
+ self.GetEventHandler().ProcessEvent(e)
+ finally:
+ self.propagating_event = False
+
+ event.Skip()
+
+ # -------------------------------------------------------------------------
+
+ def OnSetFocus(self, event):
+
+ # wxDatePickerCtrl's EVT_SET_FOCUS handler unconditionally sets the
+ # focus on the ComboCtrl element, and the combo element sets the focus
+ # on its TextCtrl element. Since we propagate the TextCtrl's
+ # EVT_SET_FOCUS up to the DatePickerCtrl, this would create an endless
+ # recursion. We avoid this here.
+
+ if not self.propagating_event:
+ event.Skip()
+
+ # -------------------------------------------------------------------------
+
+ def OnText(self, event):
+
+ # wxDatePickerCtrl's EVT_TEXT handler sends bogus EVT_DATE_CHANGED
+ # events around. We avoid this here.
+
+ pass
+
+ # -------------------------------------------------------------------------
+
+ def GetText(self):
+
+ if 'wxMSW' in wx.PlatformInfo:
+ date = self.GetValue()
+ if date.IsOk():
+ return date.FormatDate()
+ else:
+ return u""
+ else:
+ return self.combo.GetValue()
+
+ # -------------------------------------------------------------------------
+
+ def SetText(self, text):
+
+ # Don't call SetValue() if the value hasn't really changed, since this
+ # function messes with the cursor position and the selection, and under
+ # Windows, we have no way to restore the cursor.
+ if text != self.GetText():
+ if 'wxMSW' in wx.PlatformInfo:
+ date = wx.DateTime()
+ date.ParseFormat(text, '%x')
+ self.SetValue(date)
+ else:
+ self.combo.SetValue(text)
+
+ # -------------------------------------------------------------------------
+
+ def GetBackgroundColour(self, *args, **kwargs):
+
+ if 'wxMSW' in wx.PlatformInfo:
+ return wx.DatePickerCtrl.GetBackgroundColour(self, *args, **kwargs)
+ else:
+ return self.combo.GetTextCtrl().GetBackgroundColour(*args,
**kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetBackgroundColour(self, *args, **kwargs):
+
+
+ if 'wxMSW' in wx.PlatformInfo:
+ return wx.DatePickerCtrl.SetBackgroundColour(self, *args, **kwargs)
+ else:
+ return self.combo.GetTextCtrl().SetBackgroundColour(*args,
**kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetSelection(self, *args, **kwargs):
+
+ if not 'wxMSW' in wx.PlatformInfo:
+ return self.combo.GetTextCtrl().SetSelection(*args, **kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def GetInsertionPoint(self, *args, **kwargs):
+
+ return self.combo.GetTextCtrl().GetInsertionPoint(*args, **kwargs)
+
+ # -------------------------------------------------------------------------
+
+ def SetInsertionPoint(self, *args, **kwargs):
+
+ if not 'wxMSW' in wx.PlatformInfo:
+ return self.combo.GetTextCtrl().SetInsertionPoint(*args, **kwargs)
+
+# =============================================================================
# Configuration
# =============================================================================
Property changes on: trunk/gnue-forms/src/uidrivers/wx/widgets/entry.py
___________________________________________________________________
Name: svn:executable
+ *
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r10270 - in trunk/gnue-forms: . src/uidrivers/wx/widgets,
reinhard <=