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