4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
31 using System.Runtime.InteropServices;
32 using System.ComponentModel;
33 using System.Windows.Forms.Layout;
34 using System.Collections;
36 namespace System.Windows.Forms
40 [ClassInterface (ClassInterfaceType.AutoDispatch)]
41 [Designer ("System.Windows.Forms.Design.ToolStripPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
42 public class ToolStripPanel : ContainerControl, IComponent, IDisposable, IBindableComponent, IDropTarget
44 private bool done_first_layout;
45 private LayoutEngine layout_engine;
47 private Orientation orientation;
48 private ToolStripRenderer renderer;
49 private ToolStripRenderMode render_mode;
50 private Padding row_margin;
51 private ToolStripPanelRowCollection rows;
53 public ToolStripPanel () : base ()
58 this.render_mode = ToolStripRenderMode.ManagerRenderMode;
59 this.row_margin = new Padding (3, 0, 0, 0);
60 this.rows = new ToolStripPanelRowCollection (this);
63 #region Public Properties
65 [EditorBrowsable (EditorBrowsableState.Never)]
66 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
67 public override bool AllowDrop {
68 get { return base.AllowDrop; }
69 set { base.AllowDrop = value; }
73 [EditorBrowsable (EditorBrowsableState.Never)]
74 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
75 public override bool AutoScroll {
76 get { return base.AutoScroll; }
77 set { base.AutoScroll = value; }
81 [EditorBrowsable (EditorBrowsableState.Never)]
82 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
83 public new Size AutoScrollMargin {
84 get { return base.AutoScrollMargin; }
85 set { base.AutoScrollMargin = value; }
89 [EditorBrowsable (EditorBrowsableState.Never)]
90 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
91 public new Size AutoScrollMinSize {
92 get { return base.AutoScrollMinSize; }
93 set { base.AutoScrollMinSize = value; }
97 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
98 public override bool AutoSize {
99 get { return base.AutoSize; }
100 set { base.AutoSize = value; }
103 public override DockStyle Dock {
104 get { return base.Dock; }
105 set { base.Dock = value; }
108 public override LayoutEngine LayoutEngine {
110 if (this.layout_engine == null)
111 this.layout_engine = new FlowLayout ();
113 return this.layout_engine;
118 [DefaultValue (false)]
119 [EditorBrowsable (EditorBrowsableState.Advanced)]
121 get { return this.locked; }
122 set { this.locked = value; }
125 public Orientation Orientation {
126 get { return this.orientation; }
127 set { this.orientation = value; }
131 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
132 public ToolStripRenderer Renderer {
134 if (this.render_mode == ToolStripRenderMode.ManagerRenderMode)
135 return ToolStripManager.Renderer;
137 return this.renderer;
140 if (this.renderer != value) {
141 this.renderer = value;
142 this.render_mode = ToolStripRenderMode.Custom;
143 this.OnRendererChanged (EventArgs.Empty);
148 public ToolStripRenderMode RenderMode {
149 get { return this.render_mode; }
151 if (!Enum.IsDefined (typeof (ToolStripRenderMode), value))
152 throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripRenderMode", value));
154 if (value == ToolStripRenderMode.Custom && this.renderer == null)
155 throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
156 if (value == ToolStripRenderMode.Professional || value == ToolStripRenderMode.System)
157 this.Renderer = new ToolStripProfessionalRenderer ();
159 this.render_mode = value;
163 public Padding RowMargin {
164 get { return this.row_margin; }
165 set { this.row_margin = value; }
169 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
170 public ToolStripPanelRow[] Rows {
172 ToolStripPanelRow[] retval = new ToolStripPanelRow [this.rows.Count];
173 this.rows.CopyTo (retval, 0);
179 [EditorBrowsable (EditorBrowsableState.Never)]
180 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
181 public new int TabIndex {
182 get { return base.TabIndex; }
183 set { base.TabIndex = value; }
187 [EditorBrowsable (EditorBrowsableState.Never)]
188 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
189 public new bool TabStop {
190 get { return base.TabStop; }
191 set { base.TabStop = value; }
195 [EditorBrowsable (EditorBrowsableState.Never)]
196 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
197 public override string Text {
198 get { return base.Text; }
199 set { base.Text = value; }
203 #region Protected Properties
204 protected override Padding DefaultMargin {
205 get { return new Padding (0); }
208 protected override Padding DefaultPadding {
209 get { return new Padding (0); }
213 #region Public Methods
214 public void BeginInit ()
218 public void EndInit ()
222 [MonoTODO("Not implemented")]
223 public void Join (ToolStrip toolStripToDrag)
227 [MonoTODO("Not implemented")]
228 public void Join (ToolStrip toolStripToDrag, int row)
232 [MonoTODO("Not implemented")]
233 public void Join (ToolStrip toolStripToDrag, Point location)
237 [MonoTODO("Not implemented")]
238 public void Join (ToolStrip toolStripToDrag, int x, int y)
242 public ToolStripPanelRow PointToRow (Point clientLocation)
244 foreach (ToolStripPanelRow row in this.rows)
245 if (row.Bounds.Contains (clientLocation))
252 #region Protected Methods
253 protected override ControlCollection CreateControlsInstance ()
255 return new ToolStripPanelControlCollection (this);
258 protected override void Dispose (bool disposing)
260 base.Dispose (disposing);
263 protected override void OnControlAdded (ControlEventArgs e)
265 if (done_first_layout && e.Control is ToolStrip)
266 this.AddControlToRows (e.Control);
268 base.OnControlAdded (e);
271 protected override void OnControlRemoved (ControlEventArgs e)
273 base.OnControlRemoved (e);
275 foreach (ToolStripPanelRow row in this.rows)
276 if (row.controls.Contains (e.Control))
277 row.OnControlRemoved (e.Control, 0);
280 protected override void OnDockChanged (EventArgs e)
282 base.OnDockChanged (e);
285 protected override void OnLayout (LayoutEventArgs levent)
287 // Don't see any reason to layout if we aren't created
291 // The first time through, we have to layout everything where it belongs.
292 // The key is that when we resize and stuff, we don't resize or move toolstrips.
293 if (!done_first_layout) {
294 ArrayList al = new ArrayList (this.Controls);
295 al.Sort (new TabIndexComparer ());
297 foreach (ToolStrip ts in al)
298 this.AddControlToRows (ts);
300 done_first_layout = true;
303 // Lay out all the rows
304 Point position = this.DisplayRectangle.Location;
306 foreach (ToolStripPanelRow row in this.rows) {
307 row.SetBounds (new Rectangle (position, new Size (this.Width, row.Bounds.Height)));
309 position.Y += row.Bounds.Height;
312 // Find how big we are so we can autosize ourself
313 if (this.rows.Count > 0) {
314 int last_row_bottom = this.rows[this.rows.Count - 1].Bounds.Bottom;
316 if (last_row_bottom != this.Height)
317 this.SetBounds (bounds.X, bounds.Y, bounds.Width, last_row_bottom);
325 [EditorBrowsable (EditorBrowsableState.Advanced)]
326 protected override void OnPaintBackground (PaintEventArgs pevent)
328 base.OnPaintBackground (pevent);
330 this.Renderer.DrawToolStripPanelBackground (new ToolStripPanelRenderEventArgs (pevent.Graphics, this));
333 protected override void OnParentChanged (EventArgs e)
335 base.OnParentChanged (e);
338 protected virtual void OnRendererChanged (EventArgs e)
340 EventHandler eh = (EventHandler)(Events [RendererChangedEvent]);
345 protected override void OnRightToLeftChanged (EventArgs e)
347 base.OnRightToLeftChanged (e);
351 #region Public Events
352 static object RendererChangedEvent = new object ();
355 [EditorBrowsable (EditorBrowsableState.Always)]
356 public new event EventHandler AutoSizeChanged {
357 add { base.AutoSizeChanged += value; }
358 remove { base.AutoSizeChanged -= value; }
361 public event EventHandler RendererChanged {
362 add { Events.AddHandler (RendererChangedEvent, value); }
363 remove { Events.RemoveHandler (RendererChangedEvent, value); }
367 [EditorBrowsable (EditorBrowsableState.Never)]
368 public new event EventHandler TabIndexChanged {
369 add { base.TabIndexChanged += value; }
370 remove { base.TabIndexChanged -= value; }
374 [EditorBrowsable (EditorBrowsableState.Never)]
375 public new event EventHandler TabStopChanged {
376 add { base.TabStopChanged += value; }
377 remove { base.TabStopChanged -= value; }
381 [EditorBrowsable (EditorBrowsableState.Never)]
382 public new event EventHandler TextChanged {
383 add { base.TextChanged += value; }
384 remove { base.TextChanged -= value; }
388 #region Private Methods
389 void IDropTarget.OnDragDrop (DragEventArgs e)
391 throw new NotImplementedException ();
394 void IDropTarget.OnDragEnter (DragEventArgs e)
396 throw new NotImplementedException ();
399 void IDropTarget.OnDragLeave (EventArgs e)
401 throw new NotImplementedException ();
404 void IDropTarget.OnDragOver (DragEventArgs e)
406 throw new NotImplementedException ();
409 private void AddControlToRows (Control control)
411 if (this.rows.Count > 0)
412 if (this.rows[this.rows.Count - 1].CanMove ((ToolStrip)control)) {
413 this.rows[this.rows.Count - 1].OnControlAdded (control, 0);
417 ToolStripPanelRow new_row = new ToolStripPanelRow (this);
418 new_row.SetBounds (new Rectangle (0, 0, this.Width, 25));
419 this.rows.Add (new_row);
420 new_row.OnControlAdded (control, 0);
423 private Region FindBackgroundRegion ()
425 Region r = new Region (this.Bounds);
427 foreach (Control c in this.Controls)
428 r.Exclude (c.Bounds);
435 #region Nested Classes
437 [ListBindable (false)]
438 public class ToolStripPanelRowCollection : ArrangedElementCollection, IList, ICollection, IEnumerable
440 //private ToolStripPanel owner;
442 public ToolStripPanelRowCollection (ToolStripPanel owner) : base ()
444 //this.owner = owner;
447 public ToolStripPanelRowCollection (ToolStripPanel owner, ToolStripPanelRow[] value) : this (owner)
450 foreach (ToolStripPanelRow tspr in value)
454 public new virtual ToolStripPanelRow this [int index] {
455 get { return (ToolStripPanelRow)base[index]; }
458 #region Public Methods
459 public int Add (ToolStripPanelRow value)
461 return base.Add (value);
464 public void AddRange (ToolStripPanelRowCollection value)
467 throw new ArgumentNullException ("value");
469 foreach (ToolStripPanelRow tspr in value)
473 public void AddRange (ToolStripPanelRow[] value)
476 throw new ArgumentNullException ("value");
478 foreach (ToolStripPanelRow tspr in value)
482 public new virtual void Clear ()
487 public bool Contains (ToolStripPanelRow value)
489 return base.Contains (value);
492 public void CopyTo (ToolStripPanelRow[] array, int index)
494 base.CopyTo (array, index);
497 public int IndexOf (ToolStripPanelRow value)
499 return base.IndexOf (value);
502 public void Insert (int index, ToolStripPanelRow value)
504 base.Insert (index, value);
507 public void Remove (ToolStripPanelRow value)
512 public void RemoveAt (int index)
514 base.InternalRemoveAt (index);
518 #region IList Members
519 void IList.RemoveAt (int index)
521 base.InternalRemoveAt (index);
526 private class ToolStripPanelControlCollection : ControlCollection
528 public ToolStripPanelControlCollection (Control owner) : base (owner)
533 private class TabIndexComparer : IComparer
535 #region IComparer Members
536 public int Compare (object x, object y)
538 if (!(x is Control) || !(y is Control))
539 throw new ArgumentException ();
541 return (x as Control).TabIndex - (y as Control).TabIndex;