masked.TimeCtrl question

Thanks, Will,

I am okay with the entire field selection on entry. That is how I need it to work. The problem arises, for example, when I tab to a field and highlight it then move the pointer to a different application. The default losing focus apparently restores the original background color, but leaves the foreground white. This in effect would make it disappear if the background is white (which is the default emptyBackgroundColour.)

I am not sure what the TE_NOHIDESEL flag does, but from what I read I assumed it may cause the losing focus to restore the foreground and background. You may be telling me that I can override the gain/lose focus method to reverse the selection colors myself, but I’m not sure it is worth it at this stage of my experience unless it is something very easy to do.

Thank you very much, Will, for you prompt and detailed reply. I just wanted to get the situation explained in case It is a bug or a needed feature that someone wants to add. So don’t spend too much time on it.

Ron

···

-----Original Message-----
From: Will Sadkin [mailto:wsadkin@nameconnector.com]
Sent: Monday, March 28, 2005 1:08 PM
To: ‘wxPython-users@lists.wxwidgets.org’
Subject: RE: [wxPython-users] masked.TimeCtrl question

Ron,

I’m not actually sure what the TE_NOHIDESEL style flag does, but if it’s a standard TextCtrl

style, then you should still be able to specify it in the TimeCtrl constructor. By default,

masked.TimeCtrl uses style wx.TE_PROCESS_TAB, so you could theoretically | it with the

above flag…

However, this may not make any difference, because masked controls always set their

selection and cursor position on entry into the control if the entire text is selected when the

focus event occurs. This is because the base textctrl sets the selection to the entire contents of

the control by default on entry, which is fine for empty controls, but usually doesn’t make sense

for a masked control, timectrl included, because they’re almost never empty, and you don’t want

the usual semantics of typing to replace the entire contents of the control.

So the default MaskedEditMixin has two methods related to this,

_OnFocus() and _fixSelection(). Here’s what they say, in turn:

  def _OnFocus(self,event):
      """
      This event handler is currently necessary to work around new default
      behavior as of wxPython2.3.3;
      The TAB key auto selects the entire contents of the wx.TextCtrl *after*
      the EVT_SET_FOCUS event occurs; therefore we can't query/adjust the selection
      *here*, because it hasn't happened yet.  So to prevent this behavior, and
      preserve the correct selection when the focus event is not due to tab,
      we need to pull the following trick:
      """

dbg(‘MaskedEditMixin::_OnFocus’)

      if self.IsBeingDeleted() or self.GetParent().IsBeingDeleted():
          return
      wx.CallAfter(self._fixSelection)
      event.Skip()
      self.Refresh()
  def _fixSelection(self):
      """
      This gets called after the TAB traversal selection is made, if the
      focus event was due to this, but before the EVT_LEFT_* events if
      the focus shift was due to a mouse event.
      The trouble is that, a priori, there's no explicit notification of
      why the focus event we received.  However, the whole reason we need to
      do this is because the default behavior on TAB traveral in a wx.TextCtrl is
      now to select the entire contents of the window, something we don't want.
      So we can *now* test the selection range, and if it's "the whole text"
      we can assume the cause, change the insertion point to the start of
      the control, and deselect.
      """

dbg(‘MaskedEditMixin::_fixSelection’, indent=1)

      # can get here if called with wx.CallAfter after underlying
      # control has been destroyed on close, but after focus
      # events
      if not self or not self._mask or not self._IsEditable():

dbg(indent=0)

          return
      sel_start, sel_to = self._GetSelection()

dbg(‘sel_start, sel_to:’, sel_start, sel_to, ‘self.IsEmpty()?’, self.IsEmpty())

      if( sel_start == 0 and sel_to >= len( self._mask )   #(can be greater in numeric controls because of reserved space)
          and (not self._ctrl_constraints._autoSelect or self.IsEmpty() or self.IsDefault() ) ):
          # This isn't normally allowed, and so assume we got here by the new
          # "tab traversal" behavior, so we need to reset the selection
          # and insertion point:

dbg(‘entire text selected; resetting selection to start of control’)

          self._goHome()
          field = self._FindField(self._GetInsertionPoint())
          edit_start, edit_end = field._extent
          if field._selectOnFieldEntry:
              self._SetInsertionPoint(edit_start)
              self._SetSelection(edit_start, edit_end)
          elif field._insertRight:
              self._SetInsertionPoint(edit_end)
              self._SetSelection(edit_end, edit_end)
      elif (self._isFloat or self._isInt):
          text, signpos, right_signpos = self._getAbsValue()
          if text is None or text == self._template:
              integer = self._fields[0]
              edit_start, edit_end = integer._extent
              if integer._selectOnFieldEntry:

dbg(‘select on field entry:’)

                  self._SetInsertionPoint(edit_start)
                  self._SetSelection(edit_start, edit_end)
              elif integer._insertRight:

dbg(‘moving insertion point to end’)

                  self._SetInsertionPoint(edit_end)
                  self._SetSelection(edit_end, edit_end)
              else:

dbg(‘numeric ctrl is empty; start at beginning after sign’)

                  self._SetInsertionPoint(signpos+1)   ## Move past minus sign space if signed
                  self._SetSelection(signpos+1, signpos+1)
      elif sel_start > self._goEnd(getPosOnly=True):

dbg(‘cursor beyond the end of the user input; go to end of it’)

          self._goEnd()
      else:

dbg(‘sel_start, sel_to:’, sel_start, sel_to, ‘self._masklength:’, self._masklength)

          pass

dbg(indent=0)

You could derive your own time control variant that overrides these methods if you

need to, or you could keep track of the last selection either internally to a derivation

or externally in your application, and reapply it on a focus event.

Hope this helps,

/Will Sadkin

lib.masked author


William Sadkin

Parlance Corporation

www.nameconnector.com

-----Original Message-----
From: Shoemaker, Ronnie A. [mailto:Ronnie.A.Shoemaker@usa-spaceops.com]
Sent: Monday, March 28, 2005 1:02 PM
To:
wxPython-users@lists.wxwidgets.org
Subject: RE: [wxPython-users] masked.TimeCtrl question

Hi,

      I was successful in using the Masked Edit Colour controls and adding a DDD/ field to get what I needed, but I still kind of need the           TE_NOHIDESEL style flag. The highlighting changes the foreground color to white, which doesn't show up well on light backgrounds (when losing focus).  It is not completely invisible on the light blue background I am using, so I can live with that, or darken the background a little.

Thanks,

Ron

-----Original Message-----

From: Robin Dunn [mailto:robin@alldunn.com]

Sent: Tuesday, March 22, 2005 10:02 PM

To: wxPython-users@lists.wxwidgets.org

Subject: Re: [wxPython-users] masked.TimeCtrl question

Shoemaker, Ronnie A. wrote:

Hi All,

      > > I am trying to use the TimeCtrl for a time field. It functions great
      > > except for two things. The background changes to white when I use
      > > it, and the selection disappears when I move the mouse out of the
      > > app. We use a certain background for editable fields and a different

one for read-only.

The Masked Edit controls also have custom settings for bg

colours. See

“Coloring Behavior” at

      > http://wxpython.org/docs/api/wx.lib.masked.maskededit-module.html
      > You can set the colour to be used for "valid" like this:
      > w.SetCtrlParameters(validBackgroundColour=wx.Colour(*BG_TEXT))

and then it will be persistent. (Although I think it would

make sense

      > for it to default to GetBackgroundColour() instead of always being

“white”. Will, what do you think?)

      > > A tiny app demonstrating the problem is listed below. I tried using

the TE_NOHIDESEL style, but am not sure I did it right.

I think that TE_NOHIDESEL only works on Windows.

Robin Dunn

Software Craftsman

      > http://wxPython.org Java give you jitters? Relax with wxPython!
      > ---------------------------------------------------------------------
      > To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org

For additional commands, e-mail:

wxPython-users-help@lists.wxwidgets.org

Shoemaker, Ronnie A. wrote:

I am not sure what the TE_NOHIDESEL flag does, but from what I read I assumed it may cause the losing focus to restore the foreground and background.

No, it leaves the selection visible even if another window has the focus.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!