EditBox.cs :  » Game » RealmForge » CrayzEdsGui » Base » Widgets » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » RealmForge 
RealmForge » CrayzEdsGui » Base » Widgets » EditBox.cs
#region LGPL License

/*************************************************************************
    Crazy Eddie's GUI System (http://crayzedsgui.sourceforge.net)
    Copyright (C)2004 Paul D Turner (crayzed@users.sourceforge.net)
  
  C# Port developed by Chris McGuirk (leedgitar@latenitegames.com)
  Compatible with the Axiom 3D Engine (http://axiomengine.sf.net)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*************************************************************************/

#endregion LGPL License

using System;
using System.Text.RegularExpressions;

namespace CrayzEdsGui.Base.Widgets{
  /// <summary>
  /// Summary description for EditBox.
  /// </summary>
  public abstract class EditBox : Window {
    #region Constants

    static readonly Color DefaultNormalTextColor = new Color(0x00FFFFFF);
    static readonly Color DefaultSelectedTextColor = new Color(0x00000000);
    static readonly Color DefaultNormalSelectionColor = new Color(0x006060FF);
    static readonly Color DefaultInactiveSelectionColor = new Color(0x00808080);

    #endregion Constants

    #region Fields

    /// <summary>
    ///    True if the editbox is in read-only mode.
    /// </summary>
    protected bool readOnly;
    /// <summary>
    ///    True if the editbox text should be rendered masked.
    /// </summary>
    protected bool maskText;
    /// <summary>
    ///    Code point to use when rendering masked text.
    /// </summary>
    protected char maskCodePoint;
    /// <summary>
    ///    Maximum number of characters for this Editbox.
    /// </summary>
    protected int maxTextLength;
    /// <summary>
    ///    Position of the carat / insert-point.
    /// </summary>
    protected int caratPos;
    /// <summary>
    ///    Start of selection area.
    /// </summary>
    protected int selectionStart;
    /// <summary>
    ///    End of selection area.
    /// </summary>
    protected int selectionEnd;
    /// <summary>
    ///    true when a selection is being dragged.
    /// </summary>
    protected bool dragging;
    /// <summary>
    ///    Selection index for drag selection anchor point.
    /// </summary>
    protected int dragAnchorIdx;
    /// <summary>
    ///    Used to perform validation against text entered as input.
    /// </summary>
    protected Regex validator;
    /// <summary>
    ///    Pattern to use for validating text.
    /// </summary>
    protected string validationPattern;
    /// <summary>
    ///    Text color used normally.
    /// </summary>
    protected Color normalTextColor;
    /// <summary>
    ///    Text color used when text is highlighted.
    /// </summary>
    protected Color selectTextColor;
    /// <summary>
    ///    Color to apply to the selection brush.
    /// </summary>
    protected Color selectBrushColor;
    /// <summary>
    ///    Color to apply to the selection brush when widget is inactive / read-only.
    /// </summary>
    protected Color inactiveSelectBrushColor;

    #endregion Fields

    #region Constructor

    /// <summary>
    ///    Constructor.
    /// </summary>
    /// <param name="name">Name for this widget.</param>
    protected EditBox(string name) : base(name) {
      // default to accepting all characters
      this.ValidationString = ".*";

      // create the validator with the default options
      validator = new Regex(validationPattern);

      maskCodePoint = '*';
      maxTextLength = int.MaxValue;

      // default colors
      normalTextColor = DefaultNormalTextColor;
      selectTextColor = DefaultSelectedTextColor;
      selectBrushColor = DefaultNormalSelectionColor;
      inactiveSelectBrushColor = DefaultInactiveSelectionColor;

      text = "";
    }

    #endregion Constructor

    #region Window Members

    /// <summary>
    ///    
    /// </summary>
    /// <param name="z"></param>
    protected override void DrawSelf(float z) {
    }

    #endregion Window Members

    #region Abstract Members

    /// <summary>
    ///    Return the text code point index that is rendered closest to screen position <paramref cref="point"/>.
    /// </summary>
    /// <param name="point">Point object describing a position on the screen in pixels.</param>
    /// <returns>Code point index into the text that is rendered closest to screen position <paramref cref="point"/>.</returns>
    protected abstract int GetTextIndexFromPosition(Point point);

    #endregion Abstract Members

    #region Base Members

    #region Properties

    /// <summary>
    ///    Get/Set the current position of the carat.
    /// </summary>
    /// <value>
    ///    Index of the insert carat relative to the start of the text.
    /// </value>
    public int CaratIndex {
      get {
        return caratPos;
      }
      set {
        // make sure the new position is valid
        if(value > text.Length) {
          value = text.Length;
        }

        // only bother if the new position is different
        if(caratPos != value) {
          caratPos = value;

          OnCaratMoved(new WindowEventArgs(this));
        }
      }
    }

    /// <summary>
    ///    return true if the Editbox has input focus.
    /// </summary>
    /// <value>
    ///    true if the Editbox has keyboard input focus.
    ///    false if the Editbox does not have keyboard input focus.
    /// </value>
    public bool HasInputFocus {
      get {
        return IsActive;
      }
    }

    /// <summary>
    ///    Return true if the Editbox text is valid given the currently set validation string.
    /// </summary>
    /// <remarks>
    ///    Validation is performed by means of a regular expression.  If the text matches the regex, the text is said to have passed
    ///    validation.  If the text does not match with the regex then the text fails validation.
    /// </remarks>
    /// <value>true if the current Editbox text passes validation, false if the text does not pass validation.</value>
    public bool IsTextValid {
      get {
        return IsStringValid(text);
      }
    }

    /// <summary>
    ///    Gets/Sets the code point used when rendering masked text.
    /// </summary>
    /// <value>
    ///    Code point value representing the Unicode code point that will be rendered instead of the Editbox text
    ///    when rendering in masked mode.
    /// </value>
    public char MaskCodePoint {
      get {
        return maskCodePoint;
      }
      set {
        if(value != maskCodePoint) {
          maskCodePoint = value;

          // event trigger
          OnMaskCodePointChanged(new WindowEventArgs(this));
        }
      }
    }

    /// <summary>
    ///    Gets/Sets the maximum text length set for this Editbox.
    /// </summary>
    /// <remarks>
    ///    Depending on the validation string set, the actual length of text that can be entered may be less than the value
    ///    returned here (it will never be more).
    /// </remarks>
    /// <value>
    ///    The maximum number of code points (characters) that can be entered into this Editbox.
    /// </value>
    public int MaxTextLength {
      get {
        return maxTextLength;
      }
      set {
        if(maxTextLength != value) {
          maxTextLength = value;

          // trigger max length changed event
          WindowEventArgs e = new WindowEventArgs(this);
          OnMaximumTextLengthChanged(e);

          // trim string
          if(text.Length > maxTextLength) {
            text = text.Substring(0, maxTextLength);
            OnTextChanged(e);

            // see if the new text is valid
            if(!IsTextValid) {
              OnTextInvalidated(e);
            }
          }
        }
      }
    }

    /// <summary>
    ///    Return the currently set color to be used for rendering the Editbox selection highlight
    ///    when the Editbox is active.
    /// </summary>
    public Color NormalSelectBrushColor {
      get {
        return selectBrushColor;
      }
      set {
        selectBrushColor = value;
        RequestRedraw();
      }
    }

    /// <summary>
    ///    Return the currently set color to be used for rendering Editbox text in the normal, unselected state.
    /// </summary>
    /// <value>Color object representing the ARGB color that is currently set.</value>
    public Color NormalTextColor {
      get {
        return normalTextColor;
      }
      set {
        normalTextColor = value;
        RequestRedraw();
      }
    }

    /// <summary>
    ///    Return the currently set color to be used for rendering Editbox text in selected region.
    /// </summary>
    /// <value>Color object representing the ARGB color that is currently set.</value>
    public Color SelectedTextColor {
      get {
        return selectTextColor;
      }
      set {
        selectTextColor = value;
        RequestRedraw();
      }
    }

    public Color InactiveSelectBrushColor { 
      get {
        return inactiveSelectBrushColor;
      }
      set {
        inactiveSelectBrushColor = value;
        RequestRedraw();
      }
    }

    /// <summary>
    ///    Gets/Sets whether the text for the Editbox will be rendered masked.
    /// </summary>
    /// <value>
    ///    true if the Editbox text will be rendered masked using the currently set mask code point, false if the Editbox
    ///    text will be rendered as plain text.
    /// </value>
    public bool TextMasked {
      get {
        return maskText;
      }
      set {
        // only change if the setting is changed
        if(maskText != value) {
          maskText = value;
          OnMaskedRenderingModeChanged(new WindowEventArgs(this));
        }
      }
    }

    /// <summary>
    ///    Gets/Sets the read-only state of the editbox.
    /// </summary>
    /// <value>
    ///    true if the Editbox is read only and can't be edited by the user, false if the Editbox is not
    ///    read only and may be edited by the user.
    /// </value>
    public bool ReadOnly {
      get {
        return readOnly;
      }
      set {
        // only change if the setting changed
        if(readOnly != value) {
          readOnly = value;
          OnReadOnlyChanged(new WindowEventArgs(this));
        }
      }
    }

    /// <summary>
    ///    Return the current selection start point.
    /// </summary>
    /// <value>
    ///    Index of the selection start point relative to the start of the text.  If no selection is defined this function returns
    ///    the position of the carat.
    ///  </value>
    public int SelectionStartIndex {
      get {
        return (selectionStart != selectionEnd) ? selectionStart : caratPos;
      }
    }

    /// <summary>
    ///    Return the current selection end point.
    /// </summary>
    /// <value>
    ///    Index of the selection end point relative to the start of the text.  If no selection is defined this function returns
    ///    the position of the carat.
    ///  </value>
    public int SelectionEndIndex {
      get {
        return (selectionStart != selectionEnd) ? selectionEnd : caratPos;
      }
    }

    /// <summary>
    ///    Return the length of the current selection (in code points / characters).
    /// </summary>
    /// <value>Number of code points (or characters) contained within the currently defined selection.</value>
    public int SelectionLength {
      get {
        return selectionEnd - selectionStart;
      }
    }

    /// <summary>
    ///    Get/Set the regular expression used for text validation.
    /// </summary>
    public string ValidationString {
      get {
        return validationPattern;
      }
      set {
        try {

          // recreate the regex
          validator = new Regex(value);

          validationPattern = value;
        }
        catch {
          throw new InvalidRequestException("The Editbox named {0} had the following bad validation expression set: {1}", this.Name, value);
        }

        // notification
        WindowEventArgs e = new WindowEventArgs(this);

        OnValidationStringChanged(e);

        if(!IsTextValid) {
          // also notify that the text is now invalid
          OnTextInvalidated(e);
        }
      }
    }

    #endregion Properties

    #region Methods

    /// <summary>
    ///    Clear the current selection setting.
    /// </summary>
    protected void ClearSelection() {
      // perform action only if required
      if(SelectionLength != 0) {
        SetSelection(0, 0);
      }
    }

    /// <summary>
    ///    Erase the currently selected text.
    /// </summary>
    /// <param name="modifyText">
    ///    When true, the actual text will be modified.  
    ///    When false, everything is done except erasing the characters.
    ///  </param>
    protected void EraseSelectedText(bool modifyText) {
      if(SelectionLength != 0) {
        // setup new carat position and remove selection highlight
        CaratIndex = SelectionStartIndex;
        ClearSelection();

        // erase the selected characters (if required)
        if(modifyText) {
          // remove the text
          text.Remove(SelectionStartIndex, SelectionLength);

          // trigger notifications that the text has changed
          OnTextChanged(new WindowEventArgs(this));
        }
      }
    }

    /// <summary>
    ///    Processing for the backspace key.
    /// </summary>
    protected void HandleBackspace() {
      if(!ReadOnly) {
        string tmp = text;

        if(SelectionLength != 0) {
          tmp = tmp.Remove(SelectionStartIndex, SelectionLength);

          if(IsStringValid(tmp)) {
            // erase selection using mode that does not modify 'text'
            EraseSelectedText(false);

            // set text to the newly modified string
            Text = tmp;
          }
          else {
            // trigger invalid modification attempted event
            OnInvalidEntryAttempted(new WindowEventArgs(this));
          }
        }
        else if(CaratIndex > 0) {
          tmp = tmp.Remove(caratPos - 1, 1);

          if(IsStringValid(tmp)) {
            CaratIndex = caratPos - 1;

            // set text to the newly modified string
            Text = tmp;
          }
          else {
            // trigger invalid modification attempted event
            OnInvalidEntryAttempted(new WindowEventArgs(this));
          }
        }
      }
    }

    /// <summary>
    ///    Processing for the delete key.
    /// </summary>
    protected void HandleDelete() {
      if(!ReadOnly) {
        string tmp = text;

        if(SelectionLength != 0) {
          tmp = tmp.Remove(SelectionStartIndex, SelectionLength);

          if(IsStringValid(tmp)) {
            // erase selection using mode that does not modify 'text'
            EraseSelectedText(false);

            // set text to the newly modified string
            Text = tmp;
          }
          else {
            // trigger invalid modification attempted event
            OnInvalidEntryAttempted(new WindowEventArgs(this));
          }
        }
        else if(CaratIndex < tmp.Length) {
          tmp = tmp.Remove(caratPos, 1);

          if(IsStringValid(tmp)) {
            // set text to the newly modified string
            Text = tmp;
          }
          else {
            // trigger invalid modification attempted event
            OnInvalidEntryAttempted(new WindowEventArgs(this));
          }
        }
      }

    }

    /// <summary>
    ///    Processing to move carat one character left.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleCharLeft(SystemKey sysKeys) {
      if(caratPos > 0) {
        CaratIndex = caratPos - 1;
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Processing to move carat one word left.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleWordLeft(SystemKey sysKeys) {
      if(caratPos > 0) {
        CaratIndex = TextUtil.GetWordStartIdx(text, CaratIndex);
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Processing to move carat one character right.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleCharRight(SystemKey sysKeys) {
      if(caratPos < text.Length) {
        CaratIndex = caratPos + 1;
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Processing to move carat one word right.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleWordRight(SystemKey sysKeys) {
      if(caratPos < text.Length) {
        CaratIndex = TextUtil.GetNextWordStartIdx(text, CaratIndex);
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Processing to move carat to the start of the text.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleHome(SystemKey sysKeys) {
      if(caratPos > 0) {
        CaratIndex = 0;
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Processing to move carat to the end of the text.
    /// </summary>
    /// <param name="sysKeys">Current state of the system keys.</param>
    protected void HandleEnd(SystemKey sysKeys) {
      if(caratPos < text.Length) {
        CaratIndex = text.Length;
      }

      if((sysKeys & SystemKey.Shift) > 0) {
        SetSelection(caratPos, dragAnchorIdx);
      }
      else {
        ClearSelection();
      }
    }

    /// <summary>
    ///    Using the current regex, the supplied text is validated.
    /// </summary>
    /// <param name="text">Text to validate.</param>
    /// <returns>True if the text is valid according to the validation string, false otherwise.</returns>
    protected bool IsStringValid(string text) {
      Match match = validator.Match(text);
    
      // only return true if the entire string matches the pattern
      return match.Success && (match.Index == 0) && (match.Length == text.Length);
    }

    /// <summary>
    ///    Define the current selection for the Editbox.
    /// </summary>
    /// <param name="startPos">
    ///    Index of the starting point for the selection.  If this value is greater than the number of characters in the Editbox, the
    ///    selection start will be set to the end of the text.
    /// </param>
    /// <param name="endPos">
    ///    Index of the ending point for the selection.  If this value is greater than the number of characters in the Editbox, the
    ///    selection end will be set to the end of the text.
    /// </param>
    public void SetSelection(int startPos, int endPos) {
      // ensure selection start point is within the valid range
      if(startPos > text.Length) {
        startPos = text.Length;
      }

      // ensure selection end point is within the valid range
      if(endPos > text.Length) {
        endPos = text.Length;
      }

      // swap values if start is after end
      if(startPos > endPos) {
        int tmp = endPos;
        endPos = startPos;
        startPos = tmp;
      }

      // only change state if values are different
      if((startPos != selectionStart) || endPos != selectionEnd) {
        // setup selection
        selectionStart = startPos;
        selectionEnd = endPos;

        // event trigger
        OnTextSelectionChanged(new WindowEventArgs(this));
      }
    }

    #endregion Methods

    #endregion Base Members

    #region Events

    #region Event Declarations

    /// <summary>
    ///    The read-only mode for the edit box has been changed.
    /// </summary>
    public event WindowEventHandler ReadOnlyChanged;
    /// <summary>
    ///    The masked rendering mode (password mode) has been changed.
    /// </summary>
    public event WindowEventHandler MaskedRenderingModeChanged;
    /// <summary>
    ///    The code point (character) to use for masked text has been changed.
    /// </summary>
    public event WindowEventHandler MaskCodePointChanged;
    /// <summary>
    ///    The validation string has been changed.
    /// </summary>
    public event WindowEventHandler ValidationStringChanged;
    /// <summary>
    ///    The maximum allowable string length has been changed.
    /// </summary>
    public event WindowEventHandler MaximumTextLengthChanged;
    /// <summary>
    ///    Some operation has made the current text invalid with regards to the validation string.
    /// </summary>
    public event WindowEventHandler TextInvalidated;
    /// <summary>
    ///    The user attempted to modify the text in a way that would have made it invalid.
    /// </summary>
    public event WindowEventHandler InvalidEntryAttempted;
    /// <summary>
    ///    The text carat (insert point) has changed.
    /// </summary>
    public event WindowEventHandler CaratMoved;
    /// <summary>
    ///    The current text selection has changed.
    /// </summary>
    public event WindowEventHandler TextSelectionChanged;
    /// <summary>
    ///    The number of characters in the edit box has reached the current maximum.
    /// </summary>
    public event WindowEventHandler EditboxFull;
    /// <summary>
    ///    The user has accepted the current text by pressing Return, Enter, or Tab.
    /// </summary>
    public event WindowEventHandler TextAccepted;

    #endregion Event Declarations

    #region Overridden Event Trigger Methods

    protected internal override void OnMouseButtonDown(MouseEventArgs e) {
      // base class handling
      base.OnMouseButtonDown(e);

      if(e.Button == MouseButton.Left) {
        // grab inputs
        CaptureInput();

        // handle mouse down
        ClearSelection();
        dragging = true;
        dragAnchorIdx = GetTextIndexFromPosition(e.Position);
        CaratIndex = dragAnchorIdx;

        e.Handled = true;
      }
    }

    protected internal override void OnMouseButtonUp(MouseEventArgs e) {
      // base class processing
      base.OnMouseButtonUp(e);

      if(e.Button == MouseButton.Left) {
        ReleaseInput();

        e.Handled = true;
      }
    }

    protected internal override void OnMouseDoubleClicked(MouseEventArgs e) {
      // base class processing
      base.OnMouseDoubleClicked(e);

      if(e.Button == MouseButton.Left) {
        // if masked, set up to select all
        if(TextMasked) {
          dragAnchorIdx = 0;
          CaratIndex = text.Length;
        }
        else {
          // not masked, so select the word that was double clicked
          dragAnchorIdx = TextUtil.GetWordStartIdx(text, (caratPos == text.Length) ? caratPos : caratPos + 1);
          caratPos = TextUtil.GetNextWordStartIdx(text, caratPos);
        }

        // perform actual selection operation
        SetSelection(dragAnchorIdx, caratPos);

        e.Handled = true;
      }
    }

    protected internal override void OnMouseTripleClicked(MouseEventArgs e) {
      // base class processing
      base.OnMouseTripleClicked(e);

      if(e.Button == MouseButton.Left) {
        dragAnchorIdx = 0;
        CaratIndex = text.Length;
        SetSelection(dragAnchorIdx, caratPos);
        e.Handled = true;
      }
    }

    protected internal override void OnMouseMove(MouseEventArgs e) {
      // base class processing
      base.OnMouseMove(e);

      if(dragging) {
        CaratIndex = GetTextIndexFromPosition(e.Position);
        SetSelection(caratPos, dragAnchorIdx);
      }

      e.Handled = true;
    }

    protected internal override void OnCaptureLost(GuiEventArgs e) {
      dragging = false;

      // base class processing
      base.OnCaptureLost(e);

      e.Handled = true;
    }

    protected internal override void OnCharacter(KeyEventArgs e) {
      // base class processing
      base.OnCharacter(e);

      // only need to take notice if we have focus
      if(HasInputFocus && this.Font.IsCharacterAvailable(e.Character) && !ReadOnly) {
        // backup current text
        string tmp = text;

        tmp = tmp.Remove(SelectionStartIndex, SelectionLength);

        // if there is room
        if(tmp.Length < maxTextLength) {
          tmp = tmp.Insert(SelectionStartIndex, e.Character.ToString());

          if(IsStringValid(tmp)) {
            // erase selection using mode that does not modify 'text' (we just want to update state)
            EraseSelectedText(false);

            // set text to the newly modified string
            Text = tmp;

            // advance carat
            caratPos++;
          }
          else {
            // trigger invalid modification attempted event
            OnInvalidEntryAttempted(new WindowEventArgs(this));
          }
        }
        else {
          // trigger text box full event
          OnEditboxFull(new WindowEventArgs(this));
        }
      }

      e.Handled = true;
    }

    protected internal override void OnKeyDown(KeyEventArgs e) {
      // base class processing
      base.OnKeyDown(e);

      if(HasInputFocus && !ReadOnly) {
        WindowEventArgs args = new WindowEventArgs(this);

        switch(e.KeyCode) {
          case KeyCodes.LeftShift:
          case KeyCodes.RightShift:
            if(SelectionLength == 0) {
              dragAnchorIdx = CaratIndex;
            }
            break;

          case KeyCodes.Backspace:
            HandleBackspace();
            break;

          case KeyCodes.Delete:
            HandleDelete();
            break;

          case KeyCodes.Tab:
          case KeyCodes.Return:
          case KeyCodes.Enter:
            // fire input accepted event
            OnTextAccepted(args);
            break;

          case KeyCodes.Left:
            if((e.Modifiers & SystemKey.Control) > 0) {
              HandleWordLeft(e.Modifiers);
            }
            else {
              HandleCharLeft(e.Modifiers);
            }
            break;

          case KeyCodes.Right:
            if((e.Modifiers & SystemKey.Control) > 0) {
              HandleWordRight(e.Modifiers);
            }
            else {
              HandleCharRight(e.Modifiers);
            }
            break;

          case KeyCodes.Home:
            HandleHome(e.Modifiers);
            break;

          case KeyCodes.End:
            HandleEnd(e.Modifiers);
            break;
        } // switch

        e.Handled = true;
      }
    }

    protected internal override void OnTextChanged(WindowEventArgs e) {
      // base class processing
      base.OnTextChanged(e);

      // clear selection
      ClearSelection();

      // make sure carat is within the text
      if(CaratIndex > text.Length) {
        CaratIndex = text.Length;
      }

      e.Handled = true;
    }

    #endregion Overridden Event Trigger Methods

    #region Event Trigger Methods

    /// <summary>
    ///    Event fired internally when the read only state of the Editbox has been changed.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnReadOnlyChanged(WindowEventArgs e) {
      RequestRedraw();

      if(ReadOnlyChanged != null) {
        ReadOnlyChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the masked rendering mode (password mode) has been changed
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnMaskedRenderingModeChanged(WindowEventArgs e) {
      RequestRedraw();

      if(MaskedRenderingModeChanged != null) {
        MaskedRenderingModeChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the code point to use for masked rendering has been changed.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnMaskCodePointChanged(WindowEventArgs e) {
      // if we are in masked mode, trigger a GUI redraw
      if(TextMasked) {
        RequestRedraw();
      }

      if(MaskCodePointChanged != null) {
        MaskCodePointChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the validation string is changed.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnValidationStringChanged(WindowEventArgs e) {
      if(ValidationStringChanged != null) {
        ValidationStringChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the maximum text length for the edit box is changed.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnMaximumTextLengthChanged(WindowEventArgs e) {
      if(MaximumTextLengthChanged != null) {
        MaximumTextLengthChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when something has caused the current text to now fail validation.
    /// </summary>
    /// <remarks>
    ///    This can be caused by changing the validation string or setting a maximum length that causes the
    ///    current text to be truncated.
    /// </remarks>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnTextInvalidated(WindowEventArgs e) {
      if(TextInvalidated != null)  {
        TextInvalidated(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the user attempted to make a change to the edit box that would
    ///    have caused it to fail validation.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnInvalidEntryAttempted(WindowEventArgs e) {
      if(InvalidEntryAttempted != null) {
        InvalidEntryAttempted(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the carat (insert point) position changes.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnCaratMoved(WindowEventArgs e) {
      RequestRedraw();

      if(CaratMoved != null) {
        CaratMoved(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the current text selection changes.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnTextSelectionChanged(WindowEventArgs e) {
      RequestRedraw();

      if(TextSelectionChanged != null) {
        TextSelectionChanged(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the edit box text has reached the set maximum length.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnEditboxFull(WindowEventArgs e) {
      if(EditboxFull != null) {
        EditboxFull(this, e);
      }
    }

    /// <summary>
    ///    Event fired internally when the user accepts the edit box text by pressing Return, Enter, or Tab.
    /// </summary>
    /// <param name="e">Event arguments.</param>
    protected internal virtual void OnTextAccepted(WindowEventArgs e) {
      if(TextAccepted != null) {
        TextAccepted(this, e);
      }
    }

    #endregion Event Trigger Methods
  
    #endregion Events
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.