* ImageList.cs: When the image stream is set pull all the images
[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) 2004-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Jackson Harper (jackson@ximian.com)
24 //
25
26
27 using System;
28 using System.ComponentModel;
29 using System.ComponentModel.Design;
30 using System.Drawing;
31
32
33 namespace System.Windows.Forms {
34         [DefaultEvent("SplitterMoved")]
35         [Designer("System.Windows.Forms.Design.SplitterDesigner, " + Consts.AssemblySystem_Design)]
36         [DefaultProperty("Dock")]
37         public class Splitter : Control, IMessageFilter {
38                 #region  Fields
39                 private int min_extra;
40                 private int min_size;
41                 private int move_start_x;
42                 private int move_start_y;
43
44                 private int thickness;
45                 private bool moving;
46                 private bool horz;
47
48                 private SplitterEventHandler on_splitter_moved;
49                 private SplitterEventHandler on_splitter_moving;
50
51                 private Control adjacent;
52                 #endregion      // Fields
53
54                 #region Public Constructors
55                 public Splitter ()
56                 {
57                         SetStyle (ControlStyles.UserPaint, true);
58                         SetStyle (ControlStyles.StandardClick, true);
59                         SetStyle (ControlStyles.StandardDoubleClick, true);
60                         SetStyle (ControlStyles.AllPaintingInWmPaint, true);
61                         SetStyle (ControlStyles.Selectable, false);
62
63                         Dock = DockStyle.Left;
64
65                         min_extra = 25;
66                         min_size = 25;
67                 }
68
69                 #endregion      // Public Constructors
70
71                 #region Public Instance Properties
72                 [DefaultValue(DockStyle.Left)]
73                 [Localizable(true)]
74                 public override DockStyle Dock {
75                         get { return base.Dock; }
76                         set {
77                                 if (value == base.Dock)
78                                         return;
79
80                                 switch (value) {
81                                 case DockStyle.Bottom:
82                                 case DockStyle.Top:
83                                         horz = true;
84                                         break;
85                                 case DockStyle.Left:
86                                 case DockStyle.Right:
87                                         horz = false;
88                                         break;
89                                 default:
90                                         throw new ArgumentException ("A splitter control must be docked left, right, top, or bottom.");
91                                 }
92                                 base.Dock = value;
93                         }
94                 }
95
96                 [DefaultValue(25)]
97                 [Localizable(true)]
98                 public int MinExtra {
99                         get { return min_extra; }
100                         set {
101                                 if (value < 0)
102                                         value = 0;
103                                 min_extra = value;
104                         }
105                 }
106
107                 [DefaultValue(25)]
108                 [Localizable(true)]
109                 public int MinSize {
110                         get {
111                                 return min_size;
112                         }
113                         set {
114                                 if(value < 0)
115                                         value = 0;
116                                 min_size = value;
117                         }
118                 }
119
120                 [Browsable(false)]
121                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
122                 public int SplitPosition {
123                         get {
124                                 Control adjacent = FindAdjacentControl ();
125                                 if (adjacent == null)
126                                         return -1;
127
128                                 if (horz)
129                                         return adjacent.Width;
130                                 return adjacent.Height;
131                         }
132                         set {
133                                 adjacent = FindAdjacentControl ();
134                                 if (adjacent == null)
135                                         return;
136
137                                 if (horz) {
138                                         if (adjacent.Height == value)
139                                                 return;
140                                         OnSplitterMoved (new SplitterEventArgs (Left, Top, Left, value));
141                                         return;
142                                 }
143                                 if (adjacent.Width == value)
144                                         return;
145                                 OnSplitterMoved (new SplitterEventArgs (adjacent.Width / 2, adjacent.Height / 2, value, Top));        
146                                 adjacent = null;
147                         }
148                 }
149
150                 #endregion      // Public Instance Properties
151
152                 #region Protected Instance Properties
153                 protected override CreateParams CreateParams {\r
154                         get {\r
155                                 return base.CreateParams;\r
156                         }\r
157                 }\r
158 \r
159                 protected override ImeMode DefaultImeMode {\r
160                         get {\r
161                                 return base.DefaultImeMode;\r
162                         }\r
163                 }\r
164 \r
165                 protected override Size DefaultSize {
166                         get {
167                                 return new Size (3, 3);
168                         }
169                 }
170
171                 #endregion      // Protected Instance Properties
172
173                 #region Public Instance Methods
174                 [MonoTODO]
175                 public bool PreFilterMessage(ref Message m) {
176                         return false;
177                 }
178                 #endregion      // Public Instance Methods
179
180                 #region Protected Instance Methods
181                 protected override void OnMouseDown (MouseEventArgs e)
182                 {
183                         base.OnMouseDown (e);
184
185                         if (!moving && e.Button == MouseButtons.Left) {
186                                 adjacent = FindAdjacentControl ();
187
188                                 move_start_x = e.X;
189                                 move_start_y = e.Y;
190
191                                 moving = true;
192                                 Capture = true;
193                         }
194                 }
195
196                 protected override void OnMouseMove (MouseEventArgs e)
197                 {
198
199                         base.OnMouseMove (e);
200                         if (moving) {
201                                 int x_move = e.X - move_start_x;
202                                 int y_move = e.Y - move_start_y;
203
204                                 move_start_x = e.X;
205                                 move_start_y = e.Y;
206
207                                 if (horz) {
208                                         Top = Top + y_move;
209                                 } else {
210                                         Left = Left + x_move;        
211                                 }
212
213                                 OnSplitterMoving (new SplitterEventArgs (e.X, e.Y, Left, Top));
214                         }
215                 }
216
217                 protected override void OnMouseUp (MouseEventArgs e)
218                 {
219                         base.OnMouseDown (e);
220                         moving = false;
221                         Capture = false;
222                         adjacent = null;
223                 }
224
225                 protected virtual void OnSplitterMoved (SplitterEventArgs e) {
226                         if (on_splitter_moved != null)
227                                 on_splitter_moved (this, e);
228                         Move (e.SplitX, e.SplitY);
229                 }
230
231                 protected virtual void OnSplitterMoving (SplitterEventArgs e) {
232                         if (on_splitter_moving != null)
233                                 on_splitter_moving (this, e);
234                         Move (e.SplitX, e.SplitY);
235                 }
236
237                 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
238                 {
239                         if (horz) {
240                                 if (height <= 0)
241                                         thickness = 3;
242                                 else
243                                         thickness = height;
244                         } else {
245                                 if (width <= 0)
246                                         thickness = 3;
247                                 else
248                                         thickness = width;
249                         }
250
251                         base.SetBoundsCore (x, y, width, height, specified);
252                 }
253
254                 #endregion      // Protected Instance Methods
255
256                 #region Internal & Private Methods
257                 private void Draw () {
258                         using (Graphics pdc = Parent.CreateGraphics ()) {
259                                 pdc.FillRectangle (new SolidBrush (Color.Red), ClientRectangle);
260                         }
261                 }
262
263                 private void Move (int x, int y) {
264                         if (adjacent == null)
265                                 return;
266
267                         if (horz) {
268                                 if (adjacent.Height == y)
269                                         return;
270                                 adjacent.Height = y;
271                                 return;
272                         }
273
274                         if (adjacent.Width == x)
275                                 return;
276                         
277                         adjacent.Width = x;
278
279                         Draw ();
280                 }
281
282                 private Control FindAdjacentControl () {
283                         if (Parent == null)
284                                 return null;
285
286                         foreach (Control sibling in Parent.Controls) {
287
288                                 if (!sibling.Visible)
289                                         continue;
290
291                                 switch (Dock) {
292
293                                         case DockStyle.Left:
294                                                 if (sibling.Right == Left)
295                                                         return sibling;
296                                                 break;
297
298                                         case DockStyle.Right:
299                                                 if (sibling.Left == Right)
300                                                         return sibling;
301                                                 break;
302
303                                         case DockStyle.Top:
304                                                 if (sibling.Bottom == Top)
305                                                         return sibling;
306                                                 break;
307
308                                         case DockStyle.Bottom:
309                                                 if (sibling.Top == Bottom)
310                                                         return sibling;
311                                                 break;
312                                 }
313                         }
314
315                         return null;
316                 }
317                 #endregion      // Internal & Private Methods
318
319
320                 #region Events
321                 [Browsable(false)]
322                 [EditorBrowsable(EditorBrowsableState.Never)]
323                 public new event EventHandler BackgroundImageChanged {
324                         add { base.BackgroundImageChanged += value; }
325                         remove { base.BackgroundImageChanged -= value; }
326                 }
327
328                 [Browsable(false)]
329                 [EditorBrowsable(EditorBrowsableState.Never)]
330                 public new event EventHandler Enter {
331                         add { base.Enter += value; }
332                         remove { base.Enter -= value; }
333                 }
334
335                 [Browsable(false)]
336                 [EditorBrowsable(EditorBrowsableState.Never)]
337                 public new event EventHandler FontChanged {
338                         add { base.FontChanged += value; }
339                         remove { base.FontChanged -= value; }
340                 }
341
342                 [Browsable(false)]
343                 [EditorBrowsable(EditorBrowsableState.Never)]
344                 public new event EventHandler ForeColorChanged {
345                         add { base.ForeColorChanged += value; }
346                         remove { base.ForeColorChanged -= value; }
347                 }
348
349                 [Browsable(false)]
350                 [EditorBrowsable(EditorBrowsableState.Never)]
351                 public new event EventHandler ImeModeChanged {
352                         add { base.ImeModeChanged += value; }
353                         remove { base.ImeModeChanged -= value; }
354                 }
355
356                 [Browsable(false)]
357                 [EditorBrowsable(EditorBrowsableState.Never)]
358                 public new event KeyEventHandler KeyDown {
359                         add { base.KeyDown += value; }
360                         remove { base.KeyDown -= value; }
361                 }
362
363                 [Browsable(false)]
364                 [EditorBrowsable(EditorBrowsableState.Never)]
365                 public new event KeyPressEventHandler KeyPress {
366                         add { base.KeyPress += value; }
367                         remove { base.KeyPress -= value; }
368                 }
369
370                 [Browsable(false)]
371                 [EditorBrowsable(EditorBrowsableState.Never)]
372                 public new event KeyEventHandler KeyUp {
373                         add { base.KeyUp += value; }
374                         remove { base.KeyUp -= value; }
375                 }
376
377                 [Browsable(false)]
378                 [EditorBrowsable(EditorBrowsableState.Never)]
379                 public new event EventHandler Leave {
380                         add { base.Leave += value; }
381                         remove { base.Leave -= value; }
382                 }
383
384                 [Browsable(false)]
385                 [EditorBrowsable(EditorBrowsableState.Never)]
386                 public new event EventHandler TabStopChanged {
387                         add { base.TabStopChanged += value; }
388                         remove { base.TabStopChanged -= value; }
389                 }
390
391                 [Browsable(false)]
392                 [EditorBrowsable(EditorBrowsableState.Never)]
393                 public new event EventHandler TextChanged {
394                         add { base.TextChanged += value; }
395                         remove { base.TextChanged -= value; }
396                 }
397
398                 public event SplitterEventHandler SplitterMoved {
399                         add { on_splitter_moved += value; }
400                         remove { on_splitter_moved -= value; }
401                 }
402
403                 public event SplitterEventHandler SplitterMoving {
404                         add { on_splitter_moving += value; }
405                         remove { on_splitter_moving -= value; }
406                 }
407                 #endregion
408         }
409 }
410
411