2006-10-06 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Splitter.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-2006 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Dennis Bartok     (pbartok@novell.com)
24 //
25 //
26
27 // COMPLETE
28
29 #undef Debug
30
31 using System;
32 using System.ComponentModel;
33 using System.Drawing;
34 using System.Reflection;
35 using System.Runtime.InteropServices;
36
37 namespace System.Windows.Forms {
38         [DefaultEvent("SplitterMoved")]
39         [Designer("System.Windows.Forms.Design.SplitterDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40         [DefaultProperty("Dock")]
41         public class Splitter : Control, IMessageFilter {
42                 #region Enums
43                 private enum DrawType {
44                         Initial,
45                         Redraw,
46                         Finish
47                 }
48                 #endregion      // Enums
49
50                 #region Local Variables
51                 static private Cursor           splitter_ns;
52                 static private Cursor           splitter_we;
53                 private BorderStyle             border_style;
54                 private int                     min_extra;
55                 private int                     min_size;
56                 private int                     split_position;         // Current splitter position
57                 private int                     prev_split_position;    // Previous splitter position, only valid during drag
58                 private int                     click_offset;           // Click offset from border of splitter control
59                 private int                     splitter_size;          // Size (width or height) of our splitter control
60                 private bool                    horizontal;             // true if we've got a horizontal splitter
61                 private Control                 affected;               // The control that the splitter resizes
62                 private Control                 filler;                 // The control that MinExtra prevents from being shrunk to 0 size
63                 private SplitterEventArgs       sevent;                 // We cache the object, prevents fragmentation
64                 private int                     limit_min;              // The max we're allowed to move the splitter left/up
65                 private int                     limit_max;              // The max we're allowed to move the splitter right/down
66                 private int                     split_requested;        // If the user requests a position before we have ever laid out the doc
67                 #endregion      // Local Variables
68
69                 #region Constructors
70                 static Splitter() {
71                         splitter_ns = Cursors.HSplit;
72                         splitter_we = Cursors.VSplit;
73                 }
74
75                 public Splitter() {
76
77                         min_extra = 25;
78                         min_size = 25;
79                         split_position = -1;
80                         split_requested = -1;
81                         splitter_size = 3;
82                         horizontal = false;
83                         sevent = new SplitterEventArgs(0, 0, 0, 0);
84
85                         SetStyle(ControlStyles.Selectable, false);
86                         Anchor = AnchorStyles.None;
87                         Dock = DockStyle.Left;
88
89                         Layout += new LayoutEventHandler(LayoutSplitter);
90                         this.ParentChanged += new EventHandler(ReparentSplitter);
91                         Cursor = splitter_we;
92                 }
93                 #endregion      // Constructors
94
95                 #region Public Instance Properties
96                 [Browsable(false)]
97                 [EditorBrowsable(EditorBrowsableState.Never)]
98                 public override bool AllowDrop {
99                         get {
100                                 return base.AllowDrop;
101                         }
102
103                         set {
104                                 base.AllowDrop = value;
105                         }
106                 }
107
108                 [Browsable(false)]
109                 [DefaultValue(AnchorStyles.None)]
110                 [EditorBrowsable(EditorBrowsableState.Never)]
111                 public override AnchorStyles Anchor {
112                         get {
113                                 return AnchorStyles.None;
114                         }
115
116                         set {
117                                 ;       // MS doesn't set it
118                         }
119                 }
120
121                 [Browsable(false)]
122                 [EditorBrowsable(EditorBrowsableState.Never)]
123                 public override Image BackgroundImage {
124                         get {
125                                 return base.BackgroundImage;
126                         }
127
128                         set {
129                                 base.BackgroundImage = value;
130                         }
131                 }
132
133                 [DispId(-504)]
134                 [DefaultValue (BorderStyle.None)]
135                 [MWFDescription("Sets the border style for the splitter")]
136                 [MWFCategory("Appearance")]
137                 public BorderStyle BorderStyle {
138                         get {
139                                 return border_style;
140                         }
141
142                         set {
143                                 border_style = value;
144
145                                 switch(value) {
146                                         case BorderStyle.FixedSingle: {
147                                                 splitter_size = 4;      // We don't get motion events for 1px wide windows on X11. sigh.
148                                                 break;
149                                         }
150
151                                         case BorderStyle.Fixed3D: {
152                                                 value = BorderStyle.None;
153                                                 splitter_size = 3;
154                                                 break;
155                                         }
156
157                                         case BorderStyle.None: {
158                                                 splitter_size = 3;
159                                                 break;
160                                         }
161
162                                         default: {
163                                                 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for BorderStyle", value));
164                                         }
165                                 }
166
167                                 base.InternalBorderStyle = value;
168                         }
169                 }
170
171                 [DefaultValue(DockStyle.Left)]
172                 [Localizable(true)]
173                 public override DockStyle Dock {
174                         get {
175                                 return base.Dock;
176                         }
177
178                         set {
179                                 if (!Enum.IsDefined (typeof (DockStyle), value) || (value == DockStyle.None) || (value == DockStyle.Fill)) {
180                                         throw new ArgumentException("Splitter must be docked left, top, bottom or right");
181                                 }
182
183                                 if ((value == DockStyle.Top) || (value == DockStyle.Bottom)) {
184                                         horizontal = true;
185                                         Cursor = splitter_ns;
186                                 } else {
187                                         horizontal = false;
188                                         Cursor = splitter_we;
189                                 }
190                                 base.Dock = value;
191                         }
192                 }
193
194                 [Browsable(false)]
195                 [EditorBrowsable(EditorBrowsableState.Never)]
196                 public override Font Font {
197                         get {
198                                 return base.Font;
199                         }
200
201                         set {
202                                 base.Font = value;
203                         }
204                 }
205
206                 [Browsable(false)]
207                 [EditorBrowsable(EditorBrowsableState.Never)]
208                 public override Color ForeColor {
209                         get {
210                                 return base.ForeColor;
211                         }
212
213                         set {
214                                 base.ForeColor = value;
215                         }
216                 }
217
218                 [Browsable(false)]
219                 [EditorBrowsable(EditorBrowsableState.Never)]
220                 public new ImeMode ImeMode {
221                         get {
222                                 return base.ImeMode;
223                         }
224
225                         set {
226                                 base.ImeMode = value;
227                         }
228                 }
229
230                 [DefaultValue(25)]
231                 [Localizable(true)]
232                 [MWFDescription("Sets minimum size of undocked window")]
233                 [MWFCategory("Behaviour")]
234                 public int MinExtra {
235                         get {
236                                 return min_extra;
237                         }
238
239                         set {
240                                 min_extra = value;
241                         }
242                 }
243
244                 [DefaultValue(25)]
245                 [Localizable(true)]
246                 [MWFDescription("Sets minimum size of the resized control")]
247                 [MWFCategory("Behaviour")]
248                 public int MinSize {
249                         get {
250                                 return min_size;
251                         }
252
253                         set {
254                                 min_size = value;
255                         }
256                 }
257
258                 
259                 [Browsable(false)]
260                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
261                 [MWFDescription("Current splitter position")]
262                 [MWFCategory("Layout")]
263                 public int SplitPosition {
264                         get {
265                                 affected = AffectedControl;
266                                 if (affected == null) {
267                                         return -1;
268                                 }
269
270                                 if (Capture) {
271                                         return CalculateSplitPosition();
272                                 }
273
274                                 if (horizontal) {
275                                         return affected.Height;
276                                 } else {
277                                         return affected.Width;
278                                 }
279                         }
280
281                         set {
282                                 affected = AffectedControl;
283
284                                 if (affected == null) {
285                                         split_requested = value;
286                                 }
287
288                                 if (Capture || (affected == null)) {
289                                         return;
290                                 }
291
292                                 if (horizontal) {
293                                         affected.Height = value;
294                                 } else {
295                                         affected.Width = value;
296                                 }
297                         }
298                 }
299
300                 [Browsable(false)]
301                 [EditorBrowsable(EditorBrowsableState.Never)]
302                 public bool TabStop {
303                         get {
304                                 return base.TabStop;
305                         }
306
307                         set {
308                                 base.TabStop = value;
309                         }
310                 }
311
312                 [Bindable(false)]
313                 [Browsable(false)]
314                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
315                 [EditorBrowsable(EditorBrowsableState.Never)]
316                 public override string Text {
317                         get {
318                                 return base.Text;
319                         }
320
321                         set {
322                                 base.Text = value;
323                         }
324                 }
325
326                 #endregion      // Public Instance Properties
327
328                 #region Protected Instance Properties
329                 protected override CreateParams CreateParams {
330                         get {
331                                 return base.CreateParams;
332                         }
333                 }
334
335                 protected override ImeMode DefaultImeMode {
336                         get {
337                                 return ImeMode.Disable;
338                         }
339                 }
340
341                 protected override Size DefaultSize {
342                         get {
343                                 return new Size (3, 3);
344                         }
345                 }
346                 #endregion      // Protected Instance Properties
347
348                 #region Public Instance Methods
349                 public bool PreFilterMessage(ref Message m) {
350                         return false;
351                 }
352
353                 public override string ToString() {
354                         return base.ToString () + String.Format(", MinExtra: {0}, MinSize: {1}", min_extra, min_size);
355                 }
356                 #endregion      // Public Instance Methods
357
358                 #region Protected Instance Methods
359                 protected override void OnKeyDown(KeyEventArgs e) {
360                         base.OnKeyDown (e);
361                         if (Capture && (e.KeyCode == Keys.Escape)) {
362                                 Capture = false;
363                                 DrawDragHandle(DrawType.Finish);
364                         }
365                 }
366
367                 protected override void OnMouseDown(MouseEventArgs e) {
368                         Point   pt;
369
370                         base.OnMouseDown (e);
371
372                         // Only allow if we are set up properly
373                         if ((affected == null) || (filler == null)) {
374                                 affected = AffectedControl;
375                                 filler = FillerControl;
376                         }
377
378                         if (affected == null || e.Button != MouseButtons.Left) {
379                                 return;
380                         }
381
382                         // Prepare the job
383                         Capture = true;
384
385                         // Calculate limits
386                         if (filler != null) {
387                                 if (horizontal) {
388                                         if (dock_style == DockStyle.Top) {
389                                                 limit_min = affected.Bounds.Top + min_size;
390                                                 limit_max = filler.Bounds.Bottom - min_extra + this.bounds.Top - filler.Bounds.Top;
391                                         } else {
392                                                 limit_min = filler.Bounds.Top + min_extra + this.bounds.Top - filler.Bounds.Bottom;
393                                                 limit_max = affected.Bounds.Bottom - min_size - this.Height;
394                                         }
395                                 } else {
396                                         if (dock_style == DockStyle.Left) {
397                                                 limit_min = affected.Bounds.Left + min_size;
398                                                 limit_max = filler.Bounds.Right - min_extra + this.bounds.Left - filler.Bounds.Left;
399                                         } else {
400                                                 limit_min = filler.Bounds.Left + min_extra + this.bounds.Left - filler.Bounds.Right;
401                                                 limit_max = affected.Bounds.Right - min_size - this.Width;
402                                         }
403                                 }
404                         } else {
405                                 limit_min = 0;
406                                 if (horizontal) {
407                                         limit_max = affected.Parent.Height;
408                                 } else {
409                                         limit_max = affected.Parent.Width;
410                                 }
411                         }
412
413                         #if Debug
414                                 Console.WriteLine("Sizing limits: Min:{0}, Max:{1}", limit_min, limit_max);
415                         #endif
416
417                         pt = PointToScreen(parent.PointToClient(new Point(e.X, e.Y)));
418
419                         if (horizontal) {
420                                 split_position = pt.Y;
421                                 if (dock_style == DockStyle.Top) {
422                                         click_offset = e.Y;
423                                 } else {
424                                         click_offset = -e.Y;
425                                 }
426                         } else {
427                                 split_position = pt.X;
428                                 if (dock_style == DockStyle.Left) {
429                                         click_offset = e.X;
430                                 } else {
431                                         click_offset = -e.X;
432                                 }
433                         }
434
435                         // We need to set this, in case we never get a mouse move
436                         prev_split_position = split_position;
437
438                         #if Debug
439                                 Console.WriteLine("Click-offset: {0} MouseDown split position: {1}", click_offset, split_position);
440                         #endif
441
442                         // Draw our initial handle
443                         DrawDragHandle(DrawType.Initial);
444                 }
445
446                 protected override void OnMouseMove(MouseEventArgs e) {
447                         Point   pt;
448
449                         base.OnMouseMove (e);
450
451                         if (!Capture  || e.Button != MouseButtons.Left || affected == null) {
452                                 return;
453                         }
454
455                         // We need our mouse coordinates relative to our parent
456                         pt = PointToScreen(parent.PointToClient(new Point(e.X, e.Y)));
457
458                         // Grab our new coordinates
459                         prev_split_position = split_position;
460
461                         int candidate = horizontal ? pt.Y : pt.X;
462
463                         // Enforce limit on what we send to the event
464                         if (candidate < limit_min)
465                                 candidate = limit_min;
466                         else if (candidate > limit_max)
467                                 candidate = limit_max;
468
469                         sevent.x = pt.X;
470                         sevent.y = pt.Y;
471                         sevent.split_x = horizontal ? 0 : candidate;
472                         sevent.split_y = horizontal ? candidate : 0;
473
474                         // Fire the event
475                         OnSplitterMoving(sevent);
476
477                         split_position = horizontal ? sevent.split_y : sevent.split_x;
478
479                         // Enforce limits
480                         if (split_position < limit_min) {
481                                 #if Debug
482                                         Console.WriteLine("SplitPosition {0} less than minimum {1}, setting to minimum", split_position, limit_min);
483                                 #endif
484                                 split_position = limit_min;
485                         } else if (split_position > limit_max) {
486                                 #if Debug
487                                         Console.WriteLine("SplitPosition {0} more than maximum {1}, setting to maximum", split_position, limit_max);
488                                 #endif
489                                 split_position = limit_max;
490                         }
491
492                         // Don't waste cycles
493                         if (prev_split_position != split_position) {
494                                 // Update our handle location
495                                 DrawDragHandle(DrawType.Redraw);
496                         }
497                 }
498
499                 protected override void OnMouseUp(MouseEventArgs e) {
500                         if (!Capture || e.Button != MouseButtons.Left || affected == null) {
501                                 base.OnMouseUp (e);
502                                 return;
503                         }
504
505                         Capture = false;
506                         DrawDragHandle(DrawType.Finish);
507
508                         // Resize the affected window
509                         if (horizontal) {
510                                 affected.Height = CalculateSplitPosition() - click_offset;
511                                 #if Debug
512                                         Console.WriteLine("Setting height of affected control to {0}", CalculateSplitPosition() - click_offset);
513                                 #endif
514                         } else {
515                                 affected.Width = CalculateSplitPosition() - click_offset;
516                                 #if Debug
517                                         Console.WriteLine("Setting width of affected control to {0}", CalculateSplitPosition() - click_offset);
518                                 #endif
519                         }
520
521                         base.OnMouseUp (e);
522
523                         // It seems that MS is sending some data that doesn't quite make sense
524                         // In this event. It tried to match their stuff.., not sure about split_x...
525
526                         // Prepare the event
527                         if (horizontal) {
528                                 sevent.x = 0;
529                                 sevent.y = split_position;
530                                 sevent.split_x = 200;
531                                 sevent.split_y = split_position;
532                         } else {
533                                 sevent.x = split_position;
534                                 sevent.y = 0;
535                                 sevent.split_x = split_position;
536                                 sevent.split_y = 200;
537                         }
538
539
540                         // Fire the event
541                         OnSplitterMoved(sevent);
542                 }
543
544                 protected virtual void OnSplitterMoved(SplitterEventArgs sevent) {
545                         if (SplitterMoved != null) {
546                                 SplitterMoved(this, sevent);
547                         }
548                 }
549
550                 protected virtual void OnSplitterMoving(SplitterEventArgs sevent) {
551                         if (SplitterMoving != null) {
552                                 SplitterMoving(this, sevent);
553                         }
554                 }
555
556                 protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
557                         // enforce our width / height
558                         if (horizontal) {
559                                 splitter_size = height;
560                                 if (splitter_size < 1) {
561                                         splitter_size = 3;
562                                 }
563                                 base.SetBoundsCore (x, y, width, splitter_size, specified);
564                         } else {
565                                 splitter_size = width;
566                                 if (splitter_size < 1) {
567                                         splitter_size = 3;
568                                 }
569                                 base.SetBoundsCore (x, y, splitter_size, height, specified);
570                         }
571                 }
572                 #endregion      // Protected Instance Methods
573
574                 #region Private Properties and Methods
575                 private Control AffectedControl {
576                         get {
577                                 if (parent == null) {
578                                         return null;
579                                 }
580
581                                 // Doc says the first control preceeding us in the zorder 
582                                 for (int i = parent.Controls.GetChildIndex(this) + 1; i < parent.Controls.Count; i++) {
583                                         switch(this.Dock) {
584                                                 case DockStyle.Top: {
585                                                         if (Top == parent.Controls[i].Bottom) {
586                                                                 return parent.Controls[i];
587                                                         }
588                                                         break;
589                                                 }
590
591                                                 case DockStyle.Bottom: {
592                                                         if (Bottom == parent.Controls[i].Top) {
593                                                                 return parent.Controls[i];
594                                                         }
595                                                         break;
596                                                 }
597
598                                                 case DockStyle.Left: {
599                                                         if (Left == parent.Controls[i].Right) {
600                                                                 return parent.Controls[i];
601                                                         }
602                                                         break;
603                                                 }
604
605                                                 case DockStyle.Right: {
606                                                         if (Right == parent.Controls[i].Left) {
607                                                                 return parent.Controls[i];
608                                                         }
609                                                         break;
610                                                 }
611                                         }
612                                 }
613                                 return null;
614                         }
615                 }
616
617                 private Control FillerControl {
618                         get {
619                                 if (parent == null) {
620                                         return null;
621                                 }
622
623                                 // Doc says the first control preceeding us in the zorder 
624                                 for (int i = parent.Controls.GetChildIndex(this) - 1; i >= 0; i--) {
625                                         if (parent.Controls[i].Dock == DockStyle.Fill) {
626                                                 return parent.Controls[i];
627                                         }
628                                 }
629                                 return null;
630                         }
631                 }
632
633                 private int CalculateSplitPosition() {
634                         if (horizontal) {
635                                 if (dock_style == DockStyle.Top) {
636                                         return split_position - affected.Top;
637                                 } else {
638                                         return affected.Bottom - split_position - splitter_size;
639                                 }
640                         } else {
641                                 if (dock_style == DockStyle.Left) {
642                                         return split_position - affected.Left;
643                                 } else {
644                                         return affected.Right - split_position - splitter_size;
645                                 }
646                         }
647                 }
648
649                 internal override void OnPaintInternal (PaintEventArgs e) {
650                         e.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(this.BackColor), e.ClipRectangle);
651                 }
652
653                 private void LayoutSplitter(object sender, LayoutEventArgs e) {
654                         affected = AffectedControl;
655                         filler = FillerControl;
656                         if (split_requested != -1) {
657                                 SplitPosition = split_requested;
658                                 split_requested = -1;
659                         }
660                 }
661
662                 private void ReparentSplitter(object sender, EventArgs e) {
663                         affected = null;
664                         filler = null;
665                 }
666
667                 private void DrawDragHandle(DrawType type) {
668                         Rectangle       prev;
669                         Rectangle       current;
670
671                         if (horizontal) {
672                                 prev = new Rectangle(Location.X, prev_split_position - click_offset + 1, Width, 0);
673                                 current = new Rectangle(Location.X, split_position - click_offset + 1, Width, 0);
674                         } else {
675                                 prev = new Rectangle(prev_split_position - click_offset + 1, Location.Y, 0, Height);
676                                 current = new Rectangle(split_position - click_offset + 1, Location.Y, 0, Height);
677                         }
678
679                         switch(type) {
680                                 case DrawType.Initial: {
681                                         XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
682                                         return;
683                                 }
684
685                                 case DrawType.Redraw: {
686                                         if (prev.X == current.X && prev.Y == current.Y) {
687                                                 return;
688                                         }
689
690                                         XplatUI.DrawReversibleRectangle(Parent.window.Handle, prev, 3);
691                                         XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
692                                         return;
693                                 }
694
695                                 case DrawType.Finish: {
696                                         XplatUI.DrawReversibleRectangle(Parent.window.Handle, current, 3);
697                                         return;
698                                 }
699                         }
700                 }
701                 #endregion      // Private Properties and Methods
702
703                 #region Events
704                 [Browsable(false)]
705                 [EditorBrowsable(EditorBrowsableState.Never)]
706                 public new event EventHandler BackgroundImageChanged {
707                         add { base.BackgroundImageChanged += value; }
708                         remove { base.BackgroundImageChanged -= value; }
709                 }
710
711                 [Browsable(false)]
712                 [EditorBrowsable(EditorBrowsableState.Never)]
713                 public new event EventHandler Enter {
714                         add { base.Enter += value; }
715                         remove { base.Enter -= value; }
716                 }
717
718                 [Browsable(false)]
719                 [EditorBrowsable(EditorBrowsableState.Never)]
720                 public new event EventHandler FontChanged {
721                         add { base.FontChanged += value; }
722                         remove { base.FontChanged -= value; }
723                 }
724
725                 [Browsable(false)]
726                 [EditorBrowsable(EditorBrowsableState.Never)]
727                 public new event EventHandler ForeColorChanged {
728                         add { base.ForeColorChanged += value; }
729                         remove { base.ForeColorChanged -= value; }
730                 }
731
732                 [Browsable(false)]
733                 [EditorBrowsable(EditorBrowsableState.Never)]
734                 public new event EventHandler ImeModeChanged {
735                         add { base.ImeModeChanged += value; }
736                         remove { base.ImeModeChanged -= value; }
737                 }
738
739                 [Browsable(false)]
740                 [EditorBrowsable(EditorBrowsableState.Never)]
741                 public new event KeyEventHandler KeyDown {
742                         add { base.KeyDown += value; }
743                         remove { base.KeyDown -= value; }
744                 }
745
746                 [Browsable(false)]
747                 [EditorBrowsable(EditorBrowsableState.Never)]
748                 public new event KeyPressEventHandler KeyPress {
749                         add { base.KeyPress += value; }
750                         remove { base.KeyPress -= value; }
751                 }
752
753                 [Browsable(false)]
754                 [EditorBrowsable(EditorBrowsableState.Never)]
755                 public new event KeyEventHandler KeyUp {
756                         add { base.KeyUp += value; }
757                         remove { base.KeyUp -= value; }
758                 }
759
760                 [Browsable(false)]
761                 [EditorBrowsable(EditorBrowsableState.Never)]
762                 public new event EventHandler Leave {
763                         add { base.Leave += value; }
764                         remove { base.Leave -= value; }
765                 }
766
767                 [Browsable(false)]
768                 [EditorBrowsable(EditorBrowsableState.Never)]
769                 public new event EventHandler TabStopChanged {
770                         add { base.TabStopChanged += value; }
771                         remove { base.TabStopChanged -= value; }
772                 }
773
774                 [Browsable(false)]
775                 [EditorBrowsable(EditorBrowsableState.Never)]
776                 public new event EventHandler TextChanged {
777                         add { base.TextChanged += value; }
778                         remove { base.TextChanged -= value; }
779                 }
780
781                 public event SplitterEventHandler SplitterMoved;
782                 public event SplitterEventHandler SplitterMoving;
783                 #endregion      // Events
784         }
785 }