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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Jackson Harper (jackson@ximian.com)
27 // - Change cursor when mouse is over grip
30 using System.Collections;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
34 using System.Drawing.Text;
35 using System.Drawing.Imaging;
37 namespace System.Windows.Forms {
38 [DefaultEvent("PanelClick")]
39 [Designer("System.Windows.Forms.Design.StatusBarDesigner, " + Consts.AssemblySystem_Design)]
40 [DefaultProperty("Text")]
41 public class StatusBar : Control {
43 private StatusBarPanelCollection panels;
45 private bool show_panels = false;
46 private bool sizing_grip = true;
48 internal Rectangle paint_area = new Rectangle ();
51 #region Public Constructors
52 [MonoTODO("Change cursor when mouse is over grip")]
55 base.Dock = DockStyle.Bottom;
56 Anchor = AnchorStyles.Top | AnchorStyles.Left;
59 #endregion // Public Constructors
61 #region Public Instance Properties
63 [EditorBrowsable(EditorBrowsableState.Never)]
64 public Color BackColor {
65 get { return base.BackColor; }
67 if (value == BackColor)
69 base.BackColor = value;
70 if (BackColorChanged != null)
71 BackColorChanged (this, EventArgs.Empty);
77 [EditorBrowsable(EditorBrowsableState.Never)]
78 public Image BackgroundImage {
79 get { return base.BackgroundImage; }
81 if (value == BackgroundImage)
83 base.BackgroundImage = value;
84 if (BackgroundImageChanged != null)
85 BackgroundImageChanged (this, EventArgs.Empty);
90 [DefaultValue(DockStyle.Bottom)]
91 public override DockStyle Dock {
92 get { return base.Dock; }
102 public override Font Font {
103 get { return base.Font; }
113 [EditorBrowsable(EditorBrowsableState.Never)]
114 public Color ForeColor {
115 get { return base.ForeColor; }
117 if (value == ForeColor)
119 if (ForeColorChanged != null)
120 ForeColorChanged (this, EventArgs.Empty);
126 [EditorBrowsable(EditorBrowsableState.Never)]
127 public new ImeMode ImeMode {
128 get { return base.ImeMode; }
130 if (value == ImeMode)
132 base.ImeMode = value;
133 if (ImeModeChanged != null)
134 ImeModeChanged (this, EventArgs.Empty);
138 [MergableProperty(false)]
140 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
141 public StatusBarPanelCollection Panels {
144 panels = new StatusBarPanelCollection (this);
149 [DefaultValue(false)]
150 public bool ShowPanels {
151 get { return show_panels; }
153 if (show_panels == value)
160 public bool SizingGrip {
161 get { return sizing_grip; }
163 if (sizing_grip == value)
169 [DefaultValue(false)]
170 public new bool TabStop {
171 get { return base.TabStop; }
172 set { base.TabStop = value; }
176 public override string Text {
177 get { return base.Text; }
187 #endregion Public Instance Properties
189 #region Protected Instance Properties
190 protected override CreateParams CreateParams {
192 return base.CreateParams;
196 protected override ImeMode DefaultImeMode {
197 get { return ImeMode.Disable; }
200 protected override Size DefaultSize {
201 get { return ThemeEngine.Current.StatusBarDefaultSize; }
204 #endregion // Protected Instance Properties
206 #region Public Instance Methods
207 public override string ToString () {
208 return base.ToString () + ", Panels.Count: " + Panels.Count +
209 (Panels.Count > 0 ? ", Panels[0]: " + Panels [0] : String.Empty);
212 #endregion // Public Instance Methods
214 #region Protected Instance Methods
215 protected override void CreateHandle ()
217 base.CreateHandle ();
220 protected override void Dispose (bool disposing) {
221 base.Dispose (disposing);
224 protected virtual void OnDrawItem (StatusBarDrawItemEventArgs e) {
225 if (DrawItem != null)
229 protected override void OnHandleCreated (EventArgs e) {
230 base.OnHandleCreated (e);
236 protected override void OnHandleDestroyed (EventArgs e) {
237 base.OnHandleDestroyed (e);
240 protected override void OnLayout (LayoutEventArgs e) {
244 protected override void OnMouseDown (MouseEventArgs e) {
249 float gap = ThemeEngine.Current.StatusBarHorzGapWidth;
250 for (int i = 0; i < panels.Count; i++) {
251 float x = panels [i].Width + prev_x + (i == panels.Count - 1 ? gap : gap / 2);
252 if (e.X >= prev_x && e.X <= x) {
253 OnPanelClick (new StatusBarPanelClickEventArgs (panels [i],
254 e.Button, e.Clicks, e.X, e.Y));
260 base.OnMouseDown (e);
263 protected virtual void OnPanelClick (StatusBarPanelClickEventArgs e) {
264 if (PanelClick != null)
265 PanelClick (this, e);
268 protected override void OnResize (EventArgs e)
272 if (Width <= 0 || Height <= 0)
280 protected override void WndProc(ref Message m) {
281 switch ((Msg) m.Msg) {
283 PaintEventArgs paint_event;
285 paint_event = XplatUI.PaintEventStart (Handle);
286 DoPaint (paint_event);
287 XplatUI.PaintEventEnd (Handle);
291 base.WndProc (ref m);
294 #endregion // Methods
297 #region Internal Methods
298 internal void OnDrawItemInternal (StatusBarDrawItemEventArgs e)
303 private void DoPaint (PaintEventArgs pevent)
305 if (Width <= 0 || Height <= 0 || Visible == false)
311 pevent.Graphics.DrawImage (ImageBuffer, 0, 0);
314 private void CalcPanelSizes ()
316 if (panels == null || !show_panels)
319 if (Width == 0 || Height == 0)
322 int gap = ThemeEngine.Current.StatusBarHorzGapWidth;
324 ArrayList springs = null;
325 for (int i = 0; i < panels.Count; i++) {
326 StatusBarPanel p = panels [i];
327 if (p.AutoSize == StatusBarPanelAutoSize.None) {
332 if (p.AutoSize == StatusBarPanelAutoSize.Contents) {
333 if (DeviceContext == null)
334 CreateBuffers (Width, Height);
335 int len = (int) (DeviceContext.MeasureString (p.Text, Font).Width + 0.5F);
336 p.Width = (int) (len * 1.5F);
341 if (p.AutoSize == StatusBarPanelAutoSize.Spring) {
343 springs = new ArrayList ();
353 int spring_total = springs.Count;
354 int total_width = Width - taken - ThemeEngine.Current.StatusBarSizeGripWidth;
355 for (int i = 0; i < spring_total; i++) {
356 StatusBarPanel p = (StatusBarPanel) springs [i];
357 p.Width = total_width / spring_total;
361 private void UpdateArea ()
363 paint_area.X = paint_area.Y = 0;
364 paint_area.Width = Width;
365 paint_area.Height = Height;
370 ThemeEngine.Current.DrawStatusBar (DeviceContext, this.ClientRectangle, this);
372 #endregion // Internal Methods
377 [EditorBrowsable(EditorBrowsableState.Never)]
378 public new event EventHandler BackColorChanged;
381 [EditorBrowsable(EditorBrowsableState.Never)]
382 public new event EventHandler BackgroundImageChanged;
385 [EditorBrowsable(EditorBrowsableState.Never)]
386 public new event EventHandler ForeColorChanged;
389 [EditorBrowsable(EditorBrowsableState.Never)]
390 public new event EventHandler ImeModeChanged;
392 public event StatusBarDrawItemEventHandler DrawItem;
395 [EditorBrowsable(EditorBrowsableState.Never)]
396 public new event PaintEventHandler Paint;
397 public event StatusBarPanelClickEventHandler PanelClick;
401 #region Subclass StatusBarPanelCollection
402 public class StatusBarPanelCollection : IList, ICollection, IEnumerable {
404 private StatusBar owner;
405 private ArrayList panels;
408 #region Public Constructors
409 public StatusBarPanelCollection (StatusBar owner)
414 #endregion // Public Constructors
416 #region Private & Internal Methods
417 private int AddInternal (StatusBarPanel p, bool refresh) {
419 throw new ArgumentNullException ("value");
421 panels = new ArrayList ();
423 int res = panels.Add (p);
427 owner.CalcPanelSizes ();
434 #endregion // Private & Internal Methods
436 #region Public Instance Properties
438 [EditorBrowsable(EditorBrowsableState.Never)]
439 public virtual int Count {
447 public virtual bool IsReadOnly {
448 get { return false; }
451 public virtual StatusBarPanel this [int index] {
453 if (index < 0 || index >= Count)
454 throw new ArgumentOutOfRangeException ("index");
455 return (StatusBarPanel) panels [index];
459 throw new ArgumentNullException ("index");
460 if (index < 0 || index >= Count)
461 throw new ArgumentOutOfRangeException ("index");
462 panels [index] = value;
466 #endregion // Public Instance Properties
468 #region Public Instance Methods
469 public virtual int Add (StatusBarPanel p) {
470 return AddInternal (p, true);
473 public virtual StatusBarPanel Add (string text) {
474 StatusBarPanel res = new StatusBarPanel ();
480 public virtual void AddRange (StatusBarPanel [] range) {
482 throw new ArgumentNullException ("panels");
483 if (range.Length == 0)
486 panels = new ArrayList (range.Length);
488 for (int i = 0; i < range.Length; i++)
489 AddInternal (range [i], false);
493 public virtual void Clear () {
499 public virtual bool Contains (StatusBarPanel panel) {
500 return panels.Contains (panel);
503 public virtual IEnumerator GetEnumerator () {
504 return panels.GetEnumerator ();
507 public virtual int IndexOf (StatusBarPanel panel) {
508 return panels.IndexOf (panel);
511 public virtual void Insert (int index, StatusBarPanel value) {
513 throw new ArgumentNullException ("value");
515 throw new ArgumentOutOfRangeException ("index");
516 // TODO: InvalidArgumentException for bad AutoSize values
517 // although it seems impossible to set it to a bad value
518 value.SetParent (owner);
519 panels [index] = value;
524 public virtual void Remove (StatusBarPanel panel) {
525 panels.Remove (panel);
528 public virtual void RemoveAt (int index) {
529 panels.RemoveAt (index);
532 #endregion // Public Instance Methods
534 #region IList & ICollection Interfaces
535 bool ICollection.IsSynchronized {
536 get { return panels.IsSynchronized; }
539 object ICollection.SyncRoot {
540 get { return panels.SyncRoot; }
543 void ICollection.CopyTo (Array dest, int index)
545 panels.CopyTo (dest, index);
549 object IList.this [int index] {
550 get { return panels [index]; }
551 set { panels [index] = value; }
554 int IList.Add (object value) {
555 return panels.Add (value);
558 bool IList.Contains (object panel) {
559 return panels.Contains (panel);
562 int IList.IndexOf (object panel)
564 return panels.IndexOf (panel);
567 void IList.Insert (int index, object value)
569 panels.Insert (index, value);
572 bool IList.IsFixedSize {
573 get { return false; }
576 void IList.Remove (object value)
578 panels.Remove (value);
580 #endregion // IList & ICollection Interfaces
582 #endregion // Subclass StatusBarPanelCollection