Typo error
[mono.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / UpDownBase.cs
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:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
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.
19 //
20 // Copyright (c) 2005 Novell, Inc.
21 //
22 // Authors:
23 //      Jonathan Gilbert        <logic@deltaq.org>
24 //
25 // Integration into MWF:
26 //      Peter Bartok            <pbartok@novell.com>
27 //
28
29 using System;
30 using System.Collections;
31 using System.ComponentModel;
32 using System.Drawing;
33 using System.Runtime.InteropServices;
34 using System.Windows.Forms;
35
36 namespace System.Windows.Forms
37 {
38         [ClassInterface (ClassInterfaceType.AutoDispatch)]
39         [ComVisible (true)]
40         [Designer("System.Windows.Forms.Design.UpDownBaseDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41         public abstract class UpDownBase : ContainerControl {
42                 #region UpDownSpinner Sub-class
43                 internal sealed class UpDownSpinner : Control {
44                         #region Local Variables
45                         private const int       InitialRepeatDelay = 50;
46                         private UpDownBase      owner;
47                         private Timer           tmrRepeat;
48                         private Rectangle       top_button_rect;
49                         private Rectangle       bottom_button_rect;
50                         private int             mouse_pressed;
51                         private int             mouse_x;
52                         private int             mouse_y;
53                         private int             repeat_delay;
54                         private int             repeat_counter;
55                         bool top_button_entered;
56                         bool bottom_button_entered;
57                         #endregion      // Local Variables
58
59                         #region Constructors
60                         public UpDownSpinner(UpDownBase owner)
61                         {
62                                 this.owner = owner;
63
64                                 mouse_pressed = 0;
65
66                                 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
67                                 SetStyle(ControlStyles.DoubleBuffer, true);
68                                 SetStyle(ControlStyles.Opaque, true);
69                                 SetStyle(ControlStyles.ResizeRedraw, true);
70                                 SetStyle(ControlStyles.UserPaint, true);
71                                 SetStyle(ControlStyles.FixedHeight, true);
72                                 SetStyle(ControlStyles.Selectable, false);
73
74                                 tmrRepeat = new Timer();
75
76                                 tmrRepeat.Enabled = false;
77                                 tmrRepeat.Interval = 10;
78                                 tmrRepeat.Tick += new EventHandler(tmrRepeat_Tick);
79
80                                 compute_rects();
81                         }
82                         #endregion      // Constructors
83
84                         #region Private & Internal Methods
85                         private void compute_rects ()
86                         {
87                                 int top_button_height;
88                                 int bottom_button_height;
89
90                                 top_button_height = ClientSize.Height / 2;
91                                 bottom_button_height = ClientSize.Height - top_button_height;
92
93                                 top_button_rect = new Rectangle(0, 0, ClientSize.Width, top_button_height);
94                                 bottom_button_rect = new Rectangle(0, top_button_height, ClientSize.Width, bottom_button_height);
95                         }
96
97                         private void redraw (Graphics graphics)
98                         {
99                                 VisualStyles.PushButtonState top_button_state = VisualStyles.PushButtonState.Normal;
100                                 VisualStyles.PushButtonState bottom_button_state = VisualStyles.PushButtonState.Normal;
101
102                                 if (owner.Enabled) {
103                                         if (mouse_pressed != 0) {
104                                                 if (mouse_pressed == 1 && top_button_rect.Contains(mouse_x, mouse_y))
105                                                         top_button_state = VisualStyles.PushButtonState.Pressed;
106
107                                                 if (mouse_pressed == 2 && bottom_button_rect.Contains(mouse_x, mouse_y))
108                                                         bottom_button_state = VisualStyles.PushButtonState.Pressed;
109                                         } else {
110                                                 if (top_button_entered)
111                                                         top_button_state = VisualStyles.PushButtonState.Hot;
112                                                 if (bottom_button_entered)
113                                                         bottom_button_state = VisualStyles.PushButtonState.Hot;
114                                         }
115                                 } else {
116                                         top_button_state = VisualStyles.PushButtonState.Disabled;
117                                         bottom_button_state = VisualStyles.PushButtonState.Disabled;
118                                 }
119                                 ThemeEngine.Current.UpDownBaseDrawButton (graphics, top_button_rect, true, top_button_state);
120                                 ThemeEngine.Current.UpDownBaseDrawButton (graphics, bottom_button_rect, false, bottom_button_state);
121                         }
122
123                         private void tmrRepeat_Tick (object sender, EventArgs e)
124                         {
125                                 if (repeat_delay > 1) {
126                                         repeat_counter++;
127
128                                         if (repeat_counter < repeat_delay) {
129                                                 return;
130                                         }
131
132                                         repeat_counter = 0;
133                                         repeat_delay = (repeat_delay * 3 / 4);
134                                 }
135
136                                 if (mouse_pressed == 0) {
137                                         tmrRepeat.Enabled = false;
138                                 }
139
140                                 if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y)) {
141                                         owner.UpButton();
142                                 }
143
144                                 if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y)) {
145                                         owner.DownButton();
146                                 }
147                         }
148                         #endregion      // Private & Internal Methods
149
150                         #region Protected Instance Methods
151                         protected override void OnMouseDown (MouseEventArgs e)
152                         {
153                                 if (e.Button != MouseButtons.Left) {
154                                         return;
155                                 }
156
157                                 if (top_button_rect.Contains(e.X, e.Y)) {
158                                         mouse_pressed = 1;
159                                         owner.UpButton();
160                                 } else if (bottom_button_rect.Contains(e.X, e.Y)) {
161                                         mouse_pressed = 2;
162                                         owner.DownButton();
163                                 }
164
165                                 mouse_x = e.X;
166                                 mouse_y = e.Y;
167                                 Capture = true;
168
169                                 tmrRepeat.Enabled = true;
170                                 repeat_counter = 0;
171                                 repeat_delay = InitialRepeatDelay;
172
173                                 Refresh ();
174                         }
175
176                         protected override void OnMouseMove (MouseEventArgs e)
177                         {
178                                 ButtonState before, after;
179
180                                 before = ButtonState.Normal;
181                                 if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y))
182                                         before = ButtonState.Pushed;
183                                 if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y))
184                                         before = ButtonState.Pushed;
185
186                                 mouse_x = e.X;
187                                 mouse_y = e.Y;
188
189                                 after = ButtonState.Normal;
190                                 if ((mouse_pressed == 1) && top_button_rect.Contains(mouse_x, mouse_y))
191                                         after = ButtonState.Pushed;
192                                 if ((mouse_pressed == 2) && bottom_button_rect.Contains(mouse_x, mouse_y))
193                                         after = ButtonState.Pushed;
194
195                                 bool new_top_button_entered = top_button_rect.Contains (e.Location);
196                                 bool new_bottom_button_entered = bottom_button_rect.Contains (e.Location);
197                                 
198                                 if (before != after) {
199                                         if (after == ButtonState.Pushed) {
200                                                 tmrRepeat.Enabled = true;
201                                                 repeat_counter = 0;
202                                                 repeat_delay = InitialRepeatDelay;
203
204                                                 // fire off one right now too for good luck
205                                                 if (mouse_pressed == 1)
206                                                         owner.UpButton();
207                                                 if (mouse_pressed == 2)
208                                                         owner.DownButton();
209                                         }
210                                         else
211                                                 tmrRepeat.Enabled = false;
212
213                                         top_button_entered = new_top_button_entered;
214                                         bottom_button_entered = new_bottom_button_entered;
215
216                                         Refresh ();
217                                 } else {
218                                         if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle) {
219                                                 Region area_to_invalidate = new Region ();
220                                                 bool dirty = false;
221                                                 area_to_invalidate.MakeEmpty ();
222                                                 if (top_button_entered != new_top_button_entered) {
223                                                         top_button_entered = new_top_button_entered;
224                                                         area_to_invalidate.Union (top_button_rect);
225                                                         dirty = true;
226                                                 }
227                                                 if (bottom_button_entered != new_bottom_button_entered) {
228                                                         bottom_button_entered = new_bottom_button_entered;
229                                                         area_to_invalidate.Union (bottom_button_rect);
230                                                         dirty = true;
231                                                 }
232                                                 if (dirty)
233                                                         Invalidate (area_to_invalidate);
234                                                 area_to_invalidate.Dispose ();
235                                         } else {
236                                                 top_button_entered = new_top_button_entered;
237                                                 bottom_button_entered = new_bottom_button_entered;
238                                         }
239                                 }
240                         }
241
242                         protected override void OnMouseUp(MouseEventArgs e)
243                         {
244                                 mouse_pressed = 0;
245                                 Capture = false;
246
247                                 Refresh ();
248                         }
249
250                         protected override void OnMouseWheel(MouseEventArgs e)
251                         {
252                                 if (e.Delta > 0)
253                                         owner.UpButton();
254                                 else if (e.Delta < 0)
255                                         owner.DownButton();
256                         }
257
258                         protected override void OnMouseLeave (EventArgs e)
259                         {
260                                 if (top_button_entered) {
261                                         top_button_entered = false;
262                                         if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle)
263                                                 Invalidate (top_button_rect);
264                                 }
265                                 if (bottom_button_entered) {
266                                         bottom_button_entered = false;
267                                         if (ThemeEngine.Current.UpDownBaseHasHotButtonStyle)
268                                                 Invalidate (bottom_button_rect);
269                                 }
270                         }
271
272                         protected override void OnPaint(PaintEventArgs e)
273                         {
274                                 redraw(e.Graphics);
275                         }
276
277                         protected override void OnResize(EventArgs e)
278                         {
279                                 base.OnResize(e);
280                                 compute_rects();
281                         }
282                         #endregion      // Protected Instance Methods
283                 }
284                 #endregion      // UpDownSpinner Sub-class
285
286                 internal class UpDownTextBox : TextBox {
287
288                         private UpDownBase owner;
289
290                         public UpDownTextBox (UpDownBase owner)
291                         {
292                                 this.owner = owner;
293
294                                 SetStyle (ControlStyles.FixedWidth, false);
295                                 SetStyle (ControlStyles.Selectable, false);
296                         }
297
298
299                         // The following can be shown to be present by
300                         // adding events to both the UpDown and the
301                         // internal textbox.  the textbox doesn't
302                         // generate any, and the updown generates them
303                         // all instead.
304                         protected override void OnGotFocus (EventArgs e)
305                         {
306                                 ShowSelection = true;
307                                 owner.OnGotFocus (e);
308                                 // doesn't chain up
309                         }
310
311                         protected override void OnLostFocus (EventArgs e)
312                         {
313                                 ShowSelection = false;
314                                 owner.OnLostFocus (e);
315                                 // doesn't chain up
316                         }
317
318                         protected override void OnMouseDown (MouseEventArgs e)
319                         {
320                                 // XXX look into whether or not the
321                                 // mouse event args are altered in
322                                 // some way.
323
324                                 owner.OnMouseDown (e);
325                                 base.OnMouseDown (e);
326                         }
327
328                         protected override void OnMouseUp (MouseEventArgs e)
329                         {
330                                 // XXX look into whether or not the
331                                 // mouse event args are altered in
332                                 // some way.
333
334                                 owner.OnMouseUp (e);
335                                 base.OnMouseUp (e);
336                         }
337
338                         // XXX there are likely more events that forward up to the UpDown
339                 }
340
341                 #region Local Variables
342                 internal UpDownTextBox          txtView;
343                 private UpDownSpinner           spnSpinner;
344                 private bool                    _InterceptArrowKeys = true;
345                 private LeftRightAlignment      _UpDownAlign;
346                 private bool                    changing_text;
347                 private bool                    user_edit;
348                 #endregion      // Local Variables
349
350                 #region Public Constructors
351                 public UpDownBase()
352                 {
353                         _UpDownAlign = LeftRightAlignment.Right;
354                         InternalBorderStyle = BorderStyle.Fixed3D;
355
356                         spnSpinner = new UpDownSpinner(this);
357
358                         txtView = new UpDownTextBox (this);
359                         txtView.ModifiedChanged += new EventHandler(OnChanged);
360                         txtView.AcceptsReturn = true;
361                         txtView.AutoSize = false;
362                         txtView.BorderStyle = BorderStyle.None;
363                         txtView.Location = new System.Drawing.Point(17, 17);
364                         txtView.TabIndex = TabIndex;
365
366                         spnSpinner.Width = 16;
367                         spnSpinner.Dock = DockStyle.Right;
368                         
369                         txtView.Dock = DockStyle.Fill;
370                         
371                         SuspendLayout ();
372                         Controls.Add (spnSpinner);
373                         Controls.Add (txtView); 
374                         ResumeLayout ();
375
376                         Height = PreferredHeight;
377                         base.BackColor = txtView.BackColor;
378
379                         TabIndexChanged += new EventHandler (TabIndexChangedHandler);
380                         
381                         txtView.KeyDown += new KeyEventHandler(OnTextBoxKeyDown);
382                         txtView.KeyPress += new KeyPressEventHandler(OnTextBoxKeyPress);
383 //                      txtView.LostFocus += new EventHandler(OnTextBoxLostFocus);
384                         txtView.Resize += new EventHandler(OnTextBoxResize);
385                         txtView.TextChanged += new EventHandler(OnTextBoxTextChanged);
386
387                         // So the child controls don't get auto selected when the updown is selected
388                         auto_select_child = false;
389                         SetStyle(ControlStyles.FixedHeight, true);
390                         SetStyle(ControlStyles.Selectable, true);
391                         SetStyle (ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
392                         SetStyle (ControlStyles.StandardClick | ControlStyles.UseTextForAccessibility, false);
393                 }
394                 #endregion
395
396                 #region UIA Framework Events
397                 static object UIAUpButtonClickEvent = new object ();
398
399                 internal event EventHandler UIAUpButtonClick {
400                         add { Events.AddHandler (UIAUpButtonClickEvent, value); }
401                         remove { Events.RemoveHandler (UIAUpButtonClickEvent, value); }
402                 }
403
404                 internal void OnUIAUpButtonClick (EventArgs e)
405                 {
406                         EventHandler eh = (EventHandler) Events [UIAUpButtonClickEvent];
407                         if (eh != null)
408                                 eh (this, e);
409                 }
410
411                 static object UIADownButtonClickEvent = new object ();
412
413                 internal event EventHandler UIADownButtonClick {
414                         add { Events.AddHandler (UIADownButtonClickEvent, value); }
415                         remove { Events.RemoveHandler (UIADownButtonClickEvent, value); }
416                 }
417
418                 internal void OnUIADownButtonClick (EventArgs e)
419                 {
420                         EventHandler eh = (EventHandler) Events [UIADownButtonClickEvent];
421                         if (eh != null)
422                                 eh (this, e);
423                 }
424                 #endregion
425
426                 #region Private Methods
427                 private void TabIndexChangedHandler (object sender, EventArgs e)
428                 {
429                         txtView.TabIndex = TabIndex;
430                 }
431
432                 internal override void OnPaintInternal (PaintEventArgs e)
433                 {
434                         e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), ClientRectangle);
435                 }
436
437                 #endregion      // Private Methods
438
439                 #region Public Instance Properties
440                 [Browsable(false)]
441                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
442                 [EditorBrowsable(EditorBrowsableState.Never)]
443                 public override bool AutoScroll {
444                         get {
445                                 return base.AutoScroll;
446                         }
447
448                         set {
449                                 base.AutoScroll = value;
450                         }
451                 }
452
453                 [Browsable(false)]
454                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
455                 [EditorBrowsable(EditorBrowsableState.Never)]
456                 public new Size AutoScrollMargin {
457                         get { return base.AutoScrollMargin; }
458                         set { base.AutoScrollMargin = value; }
459                 }
460
461                 [Browsable(false)]
462                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
463                 [EditorBrowsable(EditorBrowsableState.Never)]
464                 public new Size AutoScrollMinSize {
465                         get { return base.AutoScrollMinSize; }
466                         set { base.AutoScrollMinSize = value; }
467                 }
468
469                 [Browsable (true)]
470                 [EditorBrowsable (EditorBrowsableState.Always)]
471                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
472                 public override bool AutoSize {
473                         get { return base.AutoSize; }
474                         set { base.AutoSize = value; }
475                 }
476
477                 public override Color BackColor {
478                         get {
479                                 return base.BackColor;
480                         }
481
482                         set {
483                                 base.BackColor = value;
484                                 txtView.BackColor = value;
485                         }
486                 }
487
488                 [Browsable(false)]
489                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
490                 [EditorBrowsable(EditorBrowsableState.Never)]
491                 public override Image BackgroundImage {
492                         get {
493                                 return base.BackgroundImage;
494                         }
495                         set {
496                                 base.BackgroundImage = value;
497                                 txtView.BackgroundImage = value;
498                         }
499                 }
500
501                 [Browsable (false)]
502                 [EditorBrowsable (EditorBrowsableState.Never)]
503                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
504                 public override ImageLayout BackgroundImageLayout {
505                         get { return base.BackgroundImageLayout; }
506                         set { base.BackgroundImageLayout = value; }
507                 }
508
509                 [DefaultValue(BorderStyle.Fixed3D)]
510                 [DispId(-504)]
511                 public BorderStyle BorderStyle {
512                         get { return InternalBorderStyle; }
513                         set { InternalBorderStyle = value; }
514                 }
515
516                 public override ContextMenu ContextMenu {
517                         get {
518                                 return base.ContextMenu;
519                         }
520                         set {
521                                 base.ContextMenu = value;
522                                 txtView.ContextMenu = value;
523                                 spnSpinner.ContextMenu = value;
524                         }
525                 }
526
527                 public override ContextMenuStrip ContextMenuStrip {
528                         get { return base.ContextMenuStrip; }
529                         set {
530                                 base.ContextMenuStrip = value;
531                                 txtView.ContextMenuStrip = value;
532                                 spnSpinner.ContextMenuStrip = value;
533                         }
534                 }
535
536                 [Browsable(false)]
537                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
538                 [EditorBrowsable(EditorBrowsableState.Never)]
539                 public new DockPaddingEdges DockPadding {
540                         get { return base.DockPadding; }
541                 }
542
543                 [Browsable(false)]
544                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
545                 public override bool Focused {
546                         get {
547                                 return txtView.Focused;
548                         }
549                 }
550
551                 public override Color ForeColor {
552                         get {
553                                 return base.ForeColor;
554                         }
555                         set {
556                                 base.ForeColor = value;
557                                 txtView.ForeColor = value;
558                         }
559                 }
560
561                 [DefaultValue(true)]
562                 public bool InterceptArrowKeys {
563                         get {
564                                 return _InterceptArrowKeys;
565                         }
566                         set {
567                                 _InterceptArrowKeys = value;
568                         }
569                 }
570
571                 public override Size MaximumSize {
572                         get { return base.MaximumSize; }
573                         set { base.MaximumSize = new Size (value.Width, 0); }
574                 }
575                 
576                 public override Size MinimumSize {
577                         get { return base.MinimumSize; }
578                         set { base.MinimumSize = new Size (value.Width, 0); }
579                 }
580
581                 [Browsable(false)]
582                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
583                 [EditorBrowsable(EditorBrowsableState.Advanced)]
584                 public int PreferredHeight {
585                         get {
586                                 // For some reason, the TextBox's PreferredHeight does not
587                                 // change when the Font property is assigned. Without a
588                                 // border, it will always be Font.Height anyway.
589                                 //int text_box_preferred_height = (txtView != null) ? txtView.PreferredHeight : Font.Height;
590                                 int text_box_preferred_height = Font.Height;
591
592                                 switch (border_style) {
593                                         case BorderStyle.FixedSingle:
594                                         case BorderStyle.Fixed3D:
595                                                 text_box_preferred_height += 3; // magic number? :-)
596
597                                                 return text_box_preferred_height + 4;
598
599                                         case BorderStyle.None:
600                                         default:
601                                                 return text_box_preferred_height;
602                                 }
603                         }
604                 }
605
606                 [DefaultValue(false)]
607                 public bool ReadOnly {
608                         get {
609                                 return txtView.ReadOnly;
610                         }
611                         set {
612                                 txtView.ReadOnly = value;
613                         }
614                 }
615
616                 [Localizable(true)]
617                 public override string Text {
618                         get {
619                                 if (txtView != null) {
620                                         return txtView.Text;
621                                 }
622                                 return "";
623                         }
624                         set {
625                                 txtView.Text = value;
626                                 if (this.UserEdit)
627                                         ValidateEditText();
628
629                                 txtView.SelectionLength = 0;
630                         }
631                 }
632
633                 [DefaultValue(HorizontalAlignment.Left)]
634                 [Localizable(true)]
635                 public HorizontalAlignment TextAlign {
636                         get {
637                                 return txtView.TextAlign;
638                         }
639                         set{
640                                 txtView.TextAlign = value;
641                         }
642                 }
643
644                 [DefaultValue(LeftRightAlignment.Right)]
645                 [Localizable(true)]
646                 public LeftRightAlignment UpDownAlign {
647                         get {
648                                 return _UpDownAlign;
649                         }
650                         set {
651                                 if (_UpDownAlign != value) {
652                                         _UpDownAlign = value;
653                                         
654                                         if (value == LeftRightAlignment.Left)
655                                                 spnSpinner.Dock = DockStyle.Left;
656                                         else
657                                                 spnSpinner.Dock = DockStyle.Right;
658                                 }
659                         }
660                 }
661                 #endregion      // Public Instance Properties
662
663                 #region Protected Instance Properties
664                 protected bool ChangingText {
665                         get {
666                                 return changing_text;
667                         }
668                         set {
669                                 changing_text = value;
670                         }
671                 }
672
673                 protected override CreateParams CreateParams {
674                         get {
675                                 return base.CreateParams;
676                         }
677                 }
678
679                 protected override Size DefaultSize {
680                         get {
681                                 return new Size(120, this.PreferredHeight);
682                         }
683                 }
684
685                 protected bool UserEdit {
686                         get {
687                                 return user_edit;
688                         }
689                         set {
690                                 user_edit = value;
691                         }
692                 }
693                 #endregion      // Protected Instance Properties
694
695                 #region Public Instance Methods
696                 public abstract void DownButton ();
697                 public void Select(int start, int length)
698                 {
699                         txtView.Select(start, length);
700                 }
701
702                 public abstract void UpButton ();
703                 #endregion      // Public Instance Methods
704
705                 #region Protected Instance Methods
706                 protected virtual void OnChanged (object source, EventArgs e)
707                 {
708                 }
709
710                 protected override void OnFontChanged (EventArgs e)
711                 {
712                         txtView.Font = this.Font;
713                         Height = PreferredHeight;
714                 }
715
716                 protected override void OnHandleCreated (EventArgs e)
717                 {
718                         base.OnHandleCreated (e);
719                 }
720
721                 protected override void OnHandleDestroyed (EventArgs e)
722                 {
723                         base.OnHandleDestroyed (e);
724                 }
725
726                 protected override void OnLayout (LayoutEventArgs e)
727                 {
728                         base.OnLayout(e);
729                 }
730
731                 protected override void OnMouseDown (MouseEventArgs e)
732                 {
733                         base.OnMouseDown (e);
734                 }
735
736                 protected override void OnMouseUp (MouseEventArgs mevent)
737                 {
738                         base.OnMouseUp (mevent);
739                 }
740
741                 protected override void OnMouseWheel (MouseEventArgs e)
742                 {
743                         if (e.Delta > 0)
744                                 UpButton();
745                         else if (e.Delta < 0)
746                                 DownButton();
747                 }
748
749                 protected override void OnPaint (PaintEventArgs e)
750                 {
751                         base.OnPaint (e);
752                 }
753
754                 protected virtual void OnTextBoxKeyDown (object source, KeyEventArgs e)
755                 {
756                         if (_InterceptArrowKeys) {
757                                 if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down)) {
758                                         e.Handled = true;
759
760                                         if (e.KeyCode == Keys.Up)
761                                                 UpButton();
762                                         if (e.KeyCode == Keys.Down)
763                                                 DownButton();
764                                 }
765                         }
766
767                         OnKeyDown(e);
768                 }
769
770                 protected virtual void OnTextBoxKeyPress (object source, KeyPressEventArgs e)
771                 {
772                         if (e.KeyChar == '\r') {
773                                 e.Handled = true;
774                                 ValidateEditText();
775                         }
776                         OnKeyPress(e);
777                 }
778
779                 protected virtual void OnTextBoxLostFocus (object source, EventArgs e)
780                 {
781                         if (UserEdit) {
782                                 ValidateEditText();
783                         }
784                 }
785
786                 protected virtual void OnTextBoxResize (object source, EventArgs e)
787                 {
788                         // compute the new height, taking the border into account
789                         Height = PreferredHeight;
790
791                         // let anchoring reposition the controls
792                 }
793
794                 protected virtual void OnTextBoxTextChanged (object source, EventArgs e)
795                 {
796                         if (changing_text)
797                                 ChangingText = false;
798                         else
799                                 UserEdit = true;
800
801                         OnTextChanged(e);
802                 }
803
804                 internal override void SetBoundsCoreInternal(int x, int y, int width, int height, BoundsSpecified specified)
805                 {
806                         base.SetBoundsCoreInternal (x, y, width, Math.Min (width, PreferredHeight), specified);
807                 }
808
809                 protected abstract void UpdateEditText ();
810
811                 protected virtual void ValidateEditText ()
812                 {
813                         // to be overridden by subclassers
814                 }
815
816                 [EditorBrowsable(EditorBrowsableState.Advanced)]
817                 protected override void WndProc (ref Message m)
818                 {
819                         switch((Msg) m.Msg) {
820                         case Msg.WM_KEYUP:
821                         case Msg.WM_KEYDOWN:
822                         case Msg.WM_CHAR:
823                                 XplatUI.SendMessage (txtView.Handle, (Msg) m.Msg, m.WParam, m.LParam);
824                                 break;
825                         case Msg.WM_SETFOCUS:
826                                 ActiveControl = txtView;
827                                 break;
828                         case Msg.WM_KILLFOCUS:
829                                 ActiveControl = null;
830                                 break;
831                         default:
832                                 base.WndProc (ref m);
833                                 break;
834                         }
835                 }
836                 #endregion      // Protected Instance Methods
837
838                 #region Events
839                 [Browsable (true)]
840                 [EditorBrowsable (EditorBrowsableState.Always)]
841                 public new event EventHandler AutoSizeChanged {
842                         add { base.AutoSizeChanged += value; }
843                         remove { base.AutoSizeChanged -= value; }
844                 }
845
846                 [Browsable(false)]
847                 [EditorBrowsable(EditorBrowsableState.Never)]
848                 public new event EventHandler BackgroundImageChanged {
849                         add { base.BackgroundImageChanged += value; }
850                         remove { base.BackgroundImageChanged -= value; }
851                 }
852
853                 [Browsable (false)]
854                 [EditorBrowsable (EditorBrowsableState.Never)]
855                 public new event EventHandler BackgroundImageLayoutChanged {
856                         add { base.BackgroundImageLayoutChanged += value; }
857                         remove { base.BackgroundImageLayoutChanged -= value; }
858                 }
859
860                 [Browsable (false)]
861                 [EditorBrowsable(EditorBrowsableState.Never)]
862                 public new event EventHandler MouseEnter {
863                         add { base.MouseEnter += value; }
864                         remove { base.MouseEnter -= value; }
865                 }
866
867                 [Browsable(false)]
868                 [EditorBrowsable(EditorBrowsableState.Never)]
869                 public new event EventHandler MouseHover {
870                         add { base.MouseHover += value; }
871                         remove { base.MouseHover -= value; }
872                 }
873
874                 [Browsable(false)]
875                 [EditorBrowsable(EditorBrowsableState.Never)]
876                 public new event EventHandler MouseLeave {
877                         add { base.MouseLeave += value; }
878                         remove { base.MouseLeave -= value; }
879                 }
880
881                 [Browsable(false)]
882                 [EditorBrowsable(EditorBrowsableState.Never)]
883                 public new event MouseEventHandler MouseMove {
884                         add { base.MouseMove += value; }
885                         remove { base.MouseMove -= value; }
886                 }
887                 #endregion      // Events
888         }
889 }