public override void Construct() { if (String.IsNullOrEmpty(Border)) { Border = "border-thin"; } // Note: Cursor won't draw properly if these are changed. Click events may also break. // Widget should probably be able to handle different alignments. TextVerticalAlign = VerticalAlign.Center; TextHorizontalAlign = HorizontalAlign.Left; OnClick += (sender, args) => { if (Object.ReferenceEquals(this, Root.FocusItem)) { // This widget already has focus - move cursor to click position. var clickIndex = 0; var clickX = args.X - this.GetDrawableInterior().X; var searchIndex = 0; var font = Root.GetTileSheet(Font); while (true) { if (searchIndex == Text.Length) { clickIndex = Text.Length; break; } var glyphSize = font.GlyphSize(Text[searchIndex] - ' '); if (clickX < glyphSize.X) { clickIndex = searchIndex; if (clickX > (glyphSize.X / 2)) { clickIndex += 1; } break; } clickX -= glyphSize.X; searchIndex += 1; } Invalidate(); } else { // Take focus and move cursor to end of text. Root.SetFocus(this); CursorPosition = Text.Length; Invalidate(); } }; OnGainFocus += (sender) => this.Invalidate(); OnLoseFocus += (sender) => this.Invalidate(); OnUpdateWhileFocus += (sender) => this.Invalidate(); OnKeyPress += (sender, args) => { // Actual logic of modifying the string is outsourced. var beforeEventArgs = new BeforeTextChangeEventArgs { NewText = TextFieldLogic.Process(Text, CursorPosition, args.KeyValue, out CursorPosition), Cancelled = false }; Root.SafeCall(BeforeTextChange, this, beforeEventArgs); if (beforeEventArgs.Cancelled == false) { Text = beforeEventArgs.NewText; Root.SafeCall(OnTextChange, this); Invalidate(); } }; OnKeyDown += (sender, args) => { var beforeEventArgs = new BeforeTextChangeEventArgs { NewText = TextFieldLogic.HandleSpecialKeys(Text, CursorPosition, args.KeyValue, out CursorPosition), Cancelled = false }; Root.SafeCall(BeforeTextChange, this, beforeEventArgs); if (beforeEventArgs.Cancelled == false) { Text = beforeEventArgs.NewText; Root.SafeCall(OnTextChange, this); Invalidate(); } Root.SafeCall(OnTextChange, this); Invalidate(); }; }
public override void Construct() { if (String.IsNullOrEmpty(Border)) { Border = "border-thin"; } if (Text == null) { Text = ""; } // Note: Cursor won't draw properly if these are changed. Click events may also break. // Widget should probably be able to handle different alignments. TextVerticalAlign = VerticalAlign.Center; TextHorizontalAlign = HorizontalAlign.Left; OnClick += (sender, args) => { if (IsAnyParentHidden()) { return; } if (Object.ReferenceEquals(this, Root.FocusItem)) { // This widget already has focus - move cursor to click position. var clickIndex = 0; var clickX = args.X - this.GetDrawableInterior().X; var searchIndex = 0; var font = Root.GetTileSheet(Font); while (true) { if (searchIndex == Text.Length) { clickIndex = Text.Length; break; } var glyphSize = font.GlyphSize(Text[searchIndex] - ' '); if (clickX < glyphSize.X) { clickIndex = searchIndex; if (clickX > (glyphSize.X / 2)) { clickIndex += 1; } break; } clickX -= glyphSize.X; searchIndex += 1; } CursorPosition = clickIndex; Invalidate(); args.Handled = true; } else { // Take focus and move cursor to end of text. Root.SetFocus(this); CursorPosition = Text == null ? 0 : Text.Length; Invalidate(); args.Handled = true; } }; OnGainFocus += (sender) => this.Invalidate(); OnLoseFocus += (sender) => this.Invalidate(); OnUpdateWhileFocus += (sender) => this.Invalidate(); OnKeyUp += (sender, args) => { if (IsAnyParentHidden()) { return; } args.Handled = true; }; OnKeyPress += (sender, args) => { var font = Root.GetTileSheet(Font); var glyphSize = font.GlyphSize(' '); int numChars = 2 * (Rect.Width / glyphSize.X); if (IsAnyParentHidden()) { return; } // Actual logic of modifying the string is outsourced. var beforeEventArgs = new BeforeTextChangeEventArgs { NewText = TextFieldLogic.Process(Text, CursorPosition, args.KeyValue, out CursorPosition), Cancelled = false }; Root.SafeCall(BeforeTextChange, this, beforeEventArgs); if (beforeEventArgs.Cancelled == false) { Text = beforeEventArgs.NewText.Substring(0, Math.Min(numChars, beforeEventArgs.NewText.Length)); //Text = beforeEventArgs.NewText; Root.SafeCall(OnTextChange, this); Invalidate(); args.Handled = true; } }; OnKeyDown += (sender, args) => { if (IsAnyParentHidden()) { return; } #if XNA_BUILD if (args.KeyValue == (int)global::System.Windows.Forms.Keys.Up) { Root.SafeCall(ArrowKeyUpDown, this, 1); } else if (args.KeyValue == (int)global::System.Windows.Forms.Keys.Down) { Root.SafeCall(ArrowKeyUpDown, this, -1); } if (args.KeyValue == (int)global::System.Windows.Forms.Keys.Enter) { Root.SafeCall(OnEnter, this); } #else if (args.KeyValue == (int)Microsoft.Xna.Framework.Input.Keys.Up) { Root.SafeCall(ArrowKeyUpDown, this, 1); } else if (args.KeyValue == (int)Microsoft.Xna.Framework.Input.Keys.Down) { Root.SafeCall(ArrowKeyUpDown, this, -1); } if (args.KeyValue == (int)Microsoft.Xna.Framework.Input.Keys.Enter) { Root.SafeCall(OnEnter, this); } #endif var beforeEventArgs = new BeforeTextChangeEventArgs { NewText = TextFieldLogic.HandleSpecialKeys(Text, CursorPosition, args.KeyValue, out CursorPosition), Cancelled = false }; Root.SafeCall(BeforeTextChange, this, beforeEventArgs); if (beforeEventArgs.Cancelled == false) { Text = beforeEventArgs.NewText; Root.SafeCall(OnTextChange, this); Invalidate(); } //Root.SafeCall(OnTextChange, this); Invalidate(); args.Handled = true; }; if (HiliteOnMouseOver) { var color = TextColor; OnMouseEnter += (widget, action) => { widget.TextColor = GameSettings.Current.Colors.GetColor("Highlight", Color.DarkRed).ToVector4(); widget.Invalidate(); }; OnMouseLeave += (widget, action) => { widget.TextColor = color; widget.Invalidate(); }; } }