1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc. (http://www.novell.com)
23 // Peter Bartok pbartok@novell.com
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
33 using System.Drawing.Text;
35 using System.Runtime.InteropServices;
37 namespace System.Windows.Forms {
38 [DefaultEvent("TextChanged")]
39 [Designer("System.Windows.Forms.Design.TextBoxBaseDesigner, " + Consts.AssemblySystem_Design)]
40 public abstract class TextBoxBase : Control {
41 #region Local Variables
42 internal HorizontalAlignment alignment;
43 internal bool accepts_tab;
44 internal bool accepts_return;
45 internal bool auto_size;
46 internal CharacterCasing character_casing;
48 internal bool hide_selection;
49 internal int max_length;
50 internal bool modified;
51 internal bool multiline;
52 internal bool read_only;
53 internal bool word_wrap;
54 internal Document document;
55 internal LineTag caret_tag; // tag our cursor is in
56 internal int caret_pos; // position on the line our cursor is in (can be 0 = beginning of line)
57 internal int viewport_x; // left visible pixel
58 internal int viewport_y; // top visible pixel
59 internal HScrollBar hscroll;
60 internal VScrollBar vscroll;
61 internal ScrollBars scrollbars;
62 internal bool grabbed;
63 internal bool richtext;
64 internal int requested_height;
67 internal static bool draw_lines = false;
70 #endregion // Local Variables
72 #region Internal Constructor
73 // Constructor will go when complete, only for testing - pdb
74 internal TextBoxBase() {
75 alignment = HorizontalAlignment.Left;
76 accepts_return = false;
79 border_style = BorderStyle.Fixed3D;
80 character_casing = CharacterCasing.Normal;
82 hide_selection = true;
89 document = new Document(this);
90 requested_height = -1;
92 MouseDown += new MouseEventHandler(TextBoxBase_MouseDown);
93 MouseUp += new MouseEventHandler(TextBoxBase_MouseUp);
94 MouseMove += new MouseEventHandler(TextBoxBase_MouseMove);
95 SizeChanged += new EventHandler(TextBoxBase_SizeChanged);
96 FontChanged += new EventHandler(TextBoxBase_FontOrColorChanged);
97 ForeColorChanged += new EventHandler(TextBoxBase_FontOrColorChanged);
99 scrollbars = ScrollBars.None;
101 hscroll = new HScrollBar();
102 hscroll.ValueChanged +=new EventHandler(hscroll_ValueChanged);
103 hscroll.Enabled = true;
104 hscroll.Visible = false;
106 vscroll = new VScrollBar();
107 vscroll.Visible = false;
109 this.Controls.Add(hscroll);
110 this.Controls.Add(vscroll);
112 //SetStyle(ControlStyles.ResizeRedraw, true);
113 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
114 SetStyle(ControlStyles.UserPaint, true);
116 #endregion // Internal Constructor
118 #region Private and Internal Methods
119 internal string CaseAdjust(string s) {
120 if (character_casing == CharacterCasing.Normal) {
123 if (character_casing == CharacterCasing.Lower) {
129 #endregion // Private and Internal Methods
131 #region Public Instance Properties
132 [DefaultValue(false)]
133 public bool AcceptsTab {
139 if (value != accepts_tab) {
141 OnAcceptsTabChanged(EventArgs.Empty);
148 [RefreshProperties(RefreshProperties.Repaint)]
149 public virtual bool AutoSize {
155 if (value != auto_size) {
158 if (PreferredHeight != Height) {
159 Height = PreferredHeight;
162 OnAutoSizeChanged(EventArgs.Empty);
168 public override System.Drawing.Color BackColor {
170 return base.BackColor;
173 base.BackColor = value;
178 [EditorBrowsable(EditorBrowsableState.Never)]
179 public override System.Drawing.Image BackgroundImage {
181 return base.BackgroundImage;
184 base.BackgroundImage = value;
188 [DefaultValue(BorderStyle.Fixed3D)]
190 public BorderStyle BorderStyle {
196 if (value != border_style) {
197 border_style = value;
198 OnBorderStyleChanged(EventArgs.Empty);
204 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
205 public bool CanUndo {
212 public override System.Drawing.Color ForeColor {
214 return base.ForeColor;
217 base.ForeColor = value;
222 public bool HideSelection {
224 return hide_selection;
228 if (value != hide_selection) {
229 hide_selection = value;
230 OnHideSelectionChanged(EventArgs.Empty);
232 if (hide_selection) {
233 document.selection_visible = false;
235 document.selection_visible = true;
237 document.InvalidateSelectionArea();
242 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
243 [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
245 public string[] Lines {
252 lines = new string[l];
254 for (i = 1; i <= l; i++) {
255 lines[i - 1] = document.GetLine(i).text.ToString();
269 brush = ThemeEngine.Current.ResPool.GetSolidBrush(this.ForeColor);
271 for (i = 0; i < l; i++) {
272 document.Add(i+1, CaseAdjust(value[i]), alignment, Font, brush);
274 document.RecalculateDocument(CreateGraphics());
275 OnTextChanged(EventArgs.Empty);
279 [DefaultValue(32767)]
281 public virtual int MaxLength {
287 if (value != max_length) {
294 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
295 public bool Modified {
301 if (value != modified) {
303 OnModifiedChanged(EventArgs.Empty);
308 [DefaultValue(false)]
310 [RefreshProperties(RefreshProperties.All)]
311 public virtual bool Multiline {
317 if (value != multiline) {
320 // Make sure we update our size; the user may have already set the size before going to multiline
321 if (multiline && requested_height != -1) {
322 Height = requested_height;
323 requested_height = -1;
326 OnMultilineChanged(EventArgs.Empty);
329 document.multiline = multiline;
334 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
335 [EditorBrowsable(EditorBrowsableState.Advanced)]
336 public int PreferredHeight {
338 return this.Font.Height + 7; // FIXME - consider border style as well
342 [DefaultValue(false)]
343 public bool ReadOnly {
349 if (value != read_only) {
351 OnReadOnlyChanged(EventArgs.Empty);
357 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
358 public virtual string SelectedText {
360 return document.GetSelection();
364 document.ReplaceSelection(CaseAdjust(value));
365 OnTextChanged(EventArgs.Empty);
370 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
371 public virtual int SelectionLength {
373 return document.SelectionLength();
383 start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
385 document.CharIndexToLineTag(start + value, out line, out tag, out pos);
386 document.SetSelectionEnd(line, pos);
387 document.PositionCaret(line, pos);
389 document.SetSelectionEnd(document.selection_start.line, document.selection_start.pos);
390 document.PositionCaret(document.selection_start.line, document.selection_start.pos);
396 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
397 public int SelectionStart {
401 index = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
411 document.CharIndexToLineTag(value, out line, out tag, out pos);
412 document.SetSelectionStart(line, pos);
417 public override string Text {
419 if (document == null || document.Root == null || document.Root.text == null) {
424 return document.Root.text.ToString();
429 sb = new StringBuilder();
431 for (i = 1; i < document.Lines; i++) {
432 sb.Append(document.GetLine(i).text.ToString() + Environment.NewLine);
435 return sb.ToString();
445 lines = value.Split(new char[] {'\n'});
446 for (int i = 0; i < lines.Length; i++) {
447 if (lines[i].EndsWith("\r")) {
448 lines[i] = lines[i].Substring(0, lines[i].Length - 1);
453 line = document.GetLine(1);
454 document.SetSelectionStart(line, 0);
456 line = document.GetLine(document.Lines);
457 document.SetSelectionEnd(line, line.text.Length);
458 document.PositionCaret(line, line.text.Length);
461 document.Add(1, CaseAdjust(value), alignment, Font, ThemeEngine.Current.ResPool.GetSolidBrush(ForeColor));
462 document.RecalculateDocument(CreateGraphics());
463 line = document.GetLine(1);
464 document.SetSelectionStart(line, 0);
465 document.SetSelectionEnd(line, value.Length);
466 document.PositionCaret(line, value.Length);
469 OnTextChanged(EventArgs.Empty);
474 public virtual int TextLength {
476 if (document == null || document.Root == null || document.Root.text == null) {
481 return document.Root.text.Length;
487 for (i = 1; i < document.Lines; i++) {
488 total += document.GetLine(i).text.Length + Environment.NewLine.Length;
498 public bool WordWrap {
504 if (value != word_wrap) {
509 #endregion // Public Instance Properties
511 #region Protected Instance Properties
512 protected override CreateParams CreateParams {
514 return base.CreateParams;
518 protected override System.Drawing.Size DefaultSize {
520 return base.DefaultSize;
523 #endregion // Protected Instance Properties
525 #region Public Instance Methods
526 public void AppendText(string text) {
532 // Break the string into separate lines
533 lines = text.Split(new char[] {'\n'});
534 linecount = lines.Length;
535 for (int i = 0; i < linecount; i++) {
536 if (lines[i].EndsWith("\r")) {
537 lines[i] = lines[i].Substring(0, lines[i].Length - 1);
541 // Grab the formatting for the last element
542 document.MoveCaret(CaretDirection.CtrlEnd);
544 // Insert the first line
545 document.InsertString(document.CaretLine, document.CaretPosition, lines[0]);
547 for (int i = 1; i < linecount; i++) {
548 document.Add(document.CaretLine.LineNo+i, CaseAdjust(lines[i]), alignment, document.CaretTag.font, document.CaretTag.color);
551 document.RecalculateDocument(CreateGraphics());
552 document.MoveCaret(CaretDirection.CtrlEnd);
555 document.MoveCaret(CaretDirection.CtrlEnd);
556 document.InsertStringAtCaret(text, true);
559 OnTextChanged(EventArgs.Empty);
562 public void Clear() {
564 throw new NotImplementedException();
567 public void ClearUndo() {
569 throw new NotImplementedException();
574 throw new NotImplementedException();
579 throw new NotImplementedException();
582 public void Paste() {
584 throw new NotImplementedException();
587 public void ScrollToCaret() {
589 throw new NotImplementedException();
592 public void Select(int start, int length) {
593 SelectionStart = start;
594 SelectionLength = length;
598 public void SelectAll() {
601 last = document.GetLine(document.Lines);
602 document.SetSelectionStart(document.GetLine(1), 0);
603 document.SetSelectionEnd(last, last.text.Length);
606 public override string ToString() {
611 if (document == null) {
615 sb = new StringBuilder();
617 end = document.Lines;
619 for (i = 1; i < end; i++) {
620 sb.Append(document.GetLine(i).text.ToString() + "\n");
623 return sb.ToString();
629 #endregion // Public Instance Methods
631 #region Protected Instance Methods
632 protected override void CreateHandle() {
633 base.CreateHandle ();
636 protected override bool IsInputKey(Keys keyData) {
639 if (multiline && (accepts_return || ((keyData & Keys.Control) != 0))) {
656 protected virtual void OnAcceptsTabChanged(EventArgs e) {
657 if (AcceptsTabChanged != null) {
658 AcceptsTabChanged(this, e);
662 protected virtual void OnAutoSizeChanged(EventArgs e) {
663 if (AutoSizeChanged != null) {
664 AutoSizeChanged(this, e);
668 protected virtual void OnBorderStyleChanged(EventArgs e) {
669 if (BorderStyleChanged != null) {
670 BorderStyleChanged(this, e);
674 protected override void OnFontChanged(EventArgs e) {
675 base.OnFontChanged (e);
678 if (PreferredHeight != Height) {
679 Height = PreferredHeight;
684 protected override void OnHandleCreated(EventArgs e) {
685 base.OnHandleCreated (e);
688 protected override void OnHandleDestroyed(EventArgs e) {
689 base.OnHandleDestroyed (e);
692 protected virtual void OnHideSelectionChanged(EventArgs e) {
693 if (HideSelectionChanged != null) {
694 HideSelectionChanged(this, e);
698 protected virtual void OnModifiedChanged(EventArgs e) {
699 if (ModifiedChanged != null) {
700 ModifiedChanged(this, e);
704 protected virtual void OnMultilineChanged(EventArgs e) {
705 if (MultilineChanged != null) {
706 MultilineChanged(this, e);
710 protected virtual void OnReadOnlyChanged(EventArgs e) {
711 if (ReadOnlyChanged != null) {
712 ReadOnlyChanged(this, e);
716 protected override bool ProcessDialogKey(Keys keyData) {
717 switch (keyData & Keys.KeyCode) {
719 document.SetSelectionToCaret(true);
721 if ((Control.ModifierKeys & Keys.Control) != 0) {
722 document.MoveCaret(CaretDirection.WordBack);
724 document.MoveCaret(CaretDirection.CharBack);
730 document.SetSelectionToCaret(true);
732 if ((Control.ModifierKeys & Keys.Control) != 0) {
733 document.MoveCaret(CaretDirection.WordForward);
735 document.MoveCaret(CaretDirection.CharForward);
741 document.SetSelectionToCaret(true);
742 document.MoveCaret(CaretDirection.LineUp);
747 document.SetSelectionToCaret(true);
748 document.MoveCaret(CaretDirection.LineDown);
753 document.SetSelectionToCaret(true);
755 if ((Control.ModifierKeys & Keys.Control) != 0) {
756 document.MoveCaret(CaretDirection.CtrlHome);
758 document.MoveCaret(CaretDirection.Home);
764 document.SetSelectionToCaret(true);
766 if ((Control.ModifierKeys & Keys.Control) != 0) {
767 document.MoveCaret(CaretDirection.CtrlEnd);
769 document.MoveCaret(CaretDirection.End);
775 if (multiline && (accepts_return || ((Control.ModifierKeys & Keys.Control) != 0))) {
776 if (document.selection_visible) {
777 document.ReplaceSelection("");
779 document.SetSelectionToCaret(true);
781 document.Split(document.CaretLine, document.CaretTag, document.CaretPosition);
782 OnTextChanged(EventArgs.Empty);
783 document.UpdateView(document.CaretLine, 2, 0);
784 document.MoveCaret(CaretDirection.CharForward);
792 document.InsertChar(document.CaretLine, document.CaretPosition, '\t');
793 if (document.selection_visible) {
794 document.ReplaceSelection("");
796 document.SetSelectionToCaret(true);
798 OnTextChanged(EventArgs.Empty);
806 // delete only deletes on the line, doesn't do the combine
807 if (document.selection_visible) {
808 document.ReplaceSelection("");
810 document.SetSelectionToCaret(true);
811 if (document.CaretPosition == 0) {
812 if (document.CaretLine.LineNo > 1) {
816 line = document.GetLine(document.CaretLine.LineNo - 1);
817 new_caret_pos = line.text.Length;
819 document.Combine(line, document.CaretLine);
820 document.UpdateView(line, 1, 0);
821 document.PositionCaret(line, new_caret_pos);
822 document.UpdateCaret();
823 OnTextChanged(EventArgs.Empty);
826 document.DeleteChar(document.CaretTag, document.CaretPosition, false);
827 document.MoveCaret(CaretDirection.CharBack);
828 OnTextChanged(EventArgs.Empty);
834 // delete only deletes on the line, doesn't do the combine
835 if (document.CaretPosition == document.CaretLine.text.Length) {
836 if (document.CaretLine.LineNo < document.Lines) {
839 line = document.GetLine(document.CaretLine.LineNo + 1);
840 document.Combine(document.CaretLine, line);
841 document.UpdateView(document.CaretLine, 2, 0);
842 OnTextChanged(EventArgs.Empty);
848 check_first = document.GetLine(document.CaretLine.LineNo);
849 check_second = document.GetLine(check_first.line_no + 1);
851 Console.WriteLine("Post-UpdateView: Y of first line: {0}, second line: {1}", check_first.Y, check_second.Y);
854 // Caret doesn't move
857 document.DeleteChar(document.CaretTag, document.CaretPosition, true);
858 OnTextChanged(EventArgs.Empty);
863 return base.ProcessDialogKey (keyData);
866 protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
867 // Make sure we don't get sized bigger than we want to be
870 if (height > PreferredHeight) {
871 requested_height = height;
872 height = PreferredHeight;
873 specified |= BoundsSpecified.Height;
878 base.SetBoundsCore (x, y, width, height, specified);
881 protected override void WndProc(ref Message m) {
882 switch ((Msg)m.Msg) {
884 PaintEventArgs paint_event;
886 paint_event = XplatUI.PaintEventStart(Handle);
888 PaintControl(paint_event);
889 XplatUI.PaintEventEnd(Handle);
894 case Msg.WM_SETFOCUS: {
896 document.CaretHasFocus();
897 Console.WriteLine("Creating caret");
902 case Msg.WM_KILLFOCUS: {
904 document.CaretLostFocus();
905 Console.WriteLine("Destroying caret");
911 if (ProcessKeyEventArgs(ref m)) {
915 if (PreProcessMessage(ref m)) {
919 if (ProcessKeyMessage(ref m)) {
923 if (m.WParam.ToInt32() >= 32) { // FIXME, tabs should probably go through
924 if (document.selection_visible) {
925 document.ReplaceSelection("");
928 switch (character_casing) {
929 case CharacterCasing.Normal: {
930 document.InsertCharAtCaret((char)m.WParam, true);
931 OnTextChanged(EventArgs.Empty);
935 case CharacterCasing.Lower: {
936 document.InsertCharAtCaret(Char.ToLower((char)m.WParam), true);
937 OnTextChanged(EventArgs.Empty);
941 case CharacterCasing.Upper: {
942 document.InsertCharAtCaret(Char.ToUpper((char)m.WParam), true);
943 OnTextChanged(EventArgs.Empty);
959 #endregion // Protected Instance Methods
962 public event EventHandler AcceptsTabChanged;
963 public event EventHandler AutoSizeChanged;
965 [EditorBrowsable(EditorBrowsableState.Never)]
966 public new event EventHandler BackgroundImageChanged {
967 add { base.BackgroundImageChanged += value; }
968 remove { base.BackgroundImageChanged -= value; }
970 public event EventHandler BorderStyleChanged;
972 [EditorBrowsable(EditorBrowsableState.Advanced)]
973 public event EventHandler Click;
974 public event EventHandler HideSelectionChanged;
975 public event EventHandler ModifiedChanged;
976 public event EventHandler MultilineChanged;
978 [EditorBrowsable(EditorBrowsableState.Never)]
979 public event PaintEventHandler Paint;
980 public event EventHandler ReadOnlyChanged;
983 #region Private Methods
984 internal Document Document {
996 private void PaintControl(PaintEventArgs pevent) {
998 pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
999 //pevent.Graphics.TextRenderingHint=TextRenderingHint.AntiAlias;
1001 // Draw the viewable document
1002 document.Draw(pevent.Graphics, pevent.ClipRectangle);
1004 Rectangle rect = ClientRectangle;
1007 pevent.Graphics.DrawRectangle(ThemeEngine.Current.ResPool.GetPen(ThemeEngine.Current.ColorButtonShadow), rect);
1009 // Set the scrollbar
1010 switch (scrollbars) {
1011 case ScrollBars.Both: {
1014 case ScrollBars.Vertical: {
1017 case ScrollBars.Horizontal: {
1018 hscroll.Minimum = 0;
1019 hscroll.Maximum = document.Width - this.Width;
1031 p = new Pen(Color.Red, 1);
1033 // First, figure out from what line to what line we need to draw
1034 start = document.GetLineByPixel(pevent.ClipRectangle.Top - viewport_y, false).line_no;
1035 end = document.GetLineByPixel(pevent.ClipRectangle.Bottom - viewport_y, false).line_no;
1037 //Console.WriteLine("Starting drawing on line '{0}'", document.GetLine(start));
1038 //Console.WriteLine("Ending drawing on line '{0}'", document.GetLine(end));
1041 while (line_no <= end) {
1042 line = document.GetLine(line_no);
1045 for (int i = 0; i < line.text.Length; i++) {
1046 pevent.Graphics.DrawLine(p, (int)line.widths[i] - document.ViewPortX, line.Y - document.ViewPortY, (int)line.widths[i] - document.ViewPortX, line.Y + line.height - document.ViewPortY);
1055 private void TextBoxBase_MouseDown(object sender, MouseEventArgs e) {
1060 if (e.Button == MouseButtons.Left) {
1061 document.PositionCaret(e.X, e.Y);
1062 document.SetSelectionToCaret(true);
1063 this.grabbed = true;
1064 this.Capture = true;
1069 if (e.Button == MouseButtons.Right) {
1070 draw_lines = !draw_lines;
1072 Console.WriteLine("SelectedText: {0}, length {1}", this.SelectedText, this.SelectionLength);
1073 Console.WriteLine("Selection start: {0}", this.SelectionStart);
1075 this.SelectionStart = 10;
1076 this.SelectionLength = 5;
1081 tag = document.FindTag(e.X, e.Y, out pos, false);
1083 Console.WriteLine("Click found tag {0}, character {1}", tag, pos);
1086 case 4: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, new Font("impact", 20, FontStyle.Bold, GraphicsUnit.Pixel), ThemeEngine.Current.ResPool.GetSolidBrush(Color.Red)); break;
1087 case 1: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, new Font("arial unicode ms", 24, FontStyle.Italic, GraphicsUnit.Pixel), ThemeEngine.Current.ResPool.GetSolidBrush(Color.DarkGoldenrod)); break;
1088 case 2: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, new Font("arial", 10, FontStyle.Regular, GraphicsUnit.Pixel), ThemeEngine.Current.ResPool.GetSolidBrush(Color.Aquamarine)); break;
1089 case 3: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, new Font("times roman", 16, FontStyle.Underline, GraphicsUnit.Pixel), ThemeEngine.Current.ResPool.GetSolidBrush(Color.Turquoise)); break;
1090 case 0: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, new Font("times roman", 64, FontStyle.Italic | FontStyle.Bold, GraphicsUnit.Pixel), ThemeEngine.Current.ResPool.GetSolidBrush(Color.LightSeaGreen)); break;
1091 case 5: LineTag.FormatText(tag.line, pos, (pos+10)<line.Text.Length ? 10 : line.Text.Length - pos+1, ((TextBoxBase)sender).Font, ThemeEngine.Current.ResPool.GetSolidBrush(ForeColor)); break;
1098 // Update/Recalculate what we see
1099 document.UpdateView(line, 0);
1101 // Make sure our caret is properly positioned and sized
1102 document.AlignCaret();
1106 private void TextBoxBase_MouseUp(object sender, MouseEventArgs e) {
1107 this.Capture = false;
1108 this.grabbed = false;
1109 if (e.Button == MouseButtons.Left) {
1110 document.PositionCaret(e.X + viewport_x, e.Y + viewport_y);
1111 document.SetSelectionToCaret(false);
1112 document.DisplayCaret();
1116 #endregion // Private Methods
1119 private void TextBoxBase_SizeChanged(object sender, EventArgs e) {
1121 // First, check which scrollbars we need
1123 hscroll.Bounds = new Rectangle (ClientRectangle.Left, ClientRectangle.Bottom - hscroll.Height, Width, hscroll.Height);
1127 private void hscroll_ValueChanged(object sender, EventArgs e) {
1128 XplatUI.ScrollWindow(this.Handle, document.ViewPortX-this.hscroll.Value, 0, false);
1129 document.ViewPortX = this.hscroll.Value;
1130 document.UpdateCaret();
1131 Console.WriteLine("Dude scrolled");
1134 private void TextBoxBase_MouseMove(object sender, MouseEventArgs e) {
1135 // FIXME - handle auto-scrolling if mouse is to the right/left of the window
1137 document.PositionCaret(e.X + viewport_x, e.Y + viewport_y);
1138 document.SetSelectionToCaret(false);
1139 document.DisplayCaret();
1143 private void TextBoxBase_FontOrColorChanged(object sender, EventArgs e) {
1147 // Font changes apply to the whole document
1148 for (int i = 1; i <= document.Lines; i++) {
1149 line = document.GetLine(i);
1150 LineTag.FormatText(line, 1, line.text.Length, Font, ThemeEngine.Current.ResPool.GetSolidBrush(ForeColor));
1151 document.UpdateView(line, 0);
1153 // Make sure the caret height is matching the new font height
1154 document.AlignCaret();