diff options
Diffstat (limited to 'mcs/class/Managed.Windows.Forms/System.Windows.Forms/StatusBar.cs')
-rw-r--r-- | mcs/class/Managed.Windows.Forms/System.Windows.Forms/StatusBar.cs | 616 |
1 files changed, 616 insertions, 0 deletions
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/StatusBar.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/StatusBar.cs new file mode 100644 index 00000000000..3b87051dfe1 --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/StatusBar.cs @@ -0,0 +1,616 @@ +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// Copyright (c) 2004-2005 Novell, Inc. +// +// Authors: +// Jackson Harper (jackson@ximian.com) + +// +// TODO: +// - Change cursor when mouse is over grip +// + +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.Drawing; +using System.Drawing.Text; +using System.Drawing.Imaging; + +namespace System.Windows.Forms { + [DefaultEvent("PanelClick")] + [Designer("System.Windows.Forms.Design.StatusBarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] + [DefaultProperty("Text")] + public class StatusBar : Control { + #region Fields + private StatusBarPanelCollection panels; + + private Color back_color; + private Color fore_color; + + private bool show_panels = false; + private bool sizing_grip = true; + + #endregion // Fields + + #region Public Constructors + [MonoTODO("Change cursor when mouse is over grip")] + public StatusBar () + { + base.Dock = DockStyle.Bottom; + back_color = SystemColors.Control; + fore_color = SystemColors.ControlText; + Anchor = AnchorStyles.Top | AnchorStyles.Left; + this.TabStop = false; + this.SetStyle(ControlStyles.UserPaint | ControlStyles.Selectable, false); + } + #endregion // Public Constructors + + #region Public Instance Properties + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override Color BackColor { + get { return back_color; } + set { + if (value == BackColor) + return; + back_color = value; + if (BackColorChanged != null) + BackColorChanged (this, EventArgs.Empty); + Update (); + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override Image BackgroundImage { + get { return base.BackgroundImage; } + set { + if (value == BackgroundImage) + return; + base.BackgroundImage = value; + if (BackgroundImageChanged != null) + BackgroundImageChanged (this, EventArgs.Empty); + } + } + + [Localizable(true)] + [DefaultValue(DockStyle.Bottom)] + public override DockStyle Dock { + get { return base.Dock; } + set { + if (value == Dock) + return; + base.Dock = value; + Update (); + } + } + + [Localizable(true)] + public override Font Font { + get { return base.Font; } + set { + if (value == Font) + return; + base.Font = value; + Update (); + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override Color ForeColor { + get { return fore_color; } + set { + if (value == ForeColor) + return; + fore_color = value; + if (ForeColorChanged != null) + ForeColorChanged (this, EventArgs.Empty); + Update (); + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new ImeMode ImeMode { + get { return base.ImeMode; } + set { + if (value == ImeMode) + return; + base.ImeMode = value; + if (ImeModeChanged != null) + ImeModeChanged (this, EventArgs.Empty); + } + } + + [MergableProperty(false)] + [Localizable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public StatusBarPanelCollection Panels { + get { + if (panels == null) + panels = new StatusBarPanelCollection (this); + return panels; + } + } + + [DefaultValue(false)] + public bool ShowPanels { + get { return show_panels; } + set { + if (show_panels == value) + return; + show_panels = value; + Update (); + } + } + + [DefaultValue(true)] + public bool SizingGrip { + get { return sizing_grip; } + set { + if (sizing_grip == value) + return; + sizing_grip = value; + Update (); + } + } + + [DefaultValue(false)] + public new bool TabStop { + get { return base.TabStop; } + set { base.TabStop = value; } + } + + [Localizable(true)] + public override string Text { + get { return base.Text; } + set { + if (value == Text) + return; + base.Text = value; + Update (); + } + + } + + #endregion Public Instance Properties + + #region Protected Instance Properties + protected override CreateParams CreateParams { + get { + return base.CreateParams; + } + } + + protected override ImeMode DefaultImeMode { + get { return ImeMode.Disable; } + } + + protected override Size DefaultSize { + get { return ThemeEngine.Current.StatusBarDefaultSize; } + } + + #endregion // Protected Instance Properties + + #region Public Instance Methods + public override string ToString () { + return base.ToString () + ", Panels.Count: " + Panels.Count + + (Panels.Count > 0 ? ", Panels[0]: " + Panels [0] : String.Empty); + } + + #endregion // Public Instance Methods + + #region Protected Instance Methods + protected override void CreateHandle () + { + base.CreateHandle (); + } + + protected override void Dispose (bool disposing) { + base.Dispose (disposing); + } + + protected virtual void OnDrawItem (StatusBarDrawItemEventArgs e) { + if (DrawItem != null) + DrawItem (this, e); + } + + protected override void OnHandleCreated (EventArgs e) { + base.OnHandleCreated (e); + CalcPanelSizes (); + } + + protected override void OnHandleDestroyed (EventArgs e) { + base.OnHandleDestroyed (e); + } + + protected override void OnLayout (LayoutEventArgs e) { + base.OnLayout (e); + } + + protected override void OnMouseDown (MouseEventArgs e) { + if (panels == null) + return; + + float prev_x = 0; + float gap = ThemeEngine.Current.StatusBarHorzGapWidth; + for (int i = 0; i < panels.Count; i++) { + float x = panels [i].Width + prev_x + (i == panels.Count - 1 ? gap : gap / 2); + if (e.X >= prev_x && e.X <= x) { + OnPanelClick (new StatusBarPanelClickEventArgs (panels [i], + e.Button, e.Clicks, e.X, e.Y)); + break; + } + prev_x = x; + } + + base.OnMouseDown (e); + } + + protected virtual void OnPanelClick (StatusBarPanelClickEventArgs e) { + if (PanelClick != null) + PanelClick (this, e); + } + + protected override void OnResize (EventArgs e) + { + base.OnResize (e); + + if (Width <= 0 || Height <= 0) + return; + + Update (); + } + + protected override void WndProc(ref Message m) { + switch ((Msg) m.Msg) { + case Msg.WM_PAINT: { + PaintEventArgs paint_event; + + paint_event = XplatUI.PaintEventStart (Handle, true); + DoPaint (paint_event); + XplatUI.PaintEventEnd (Handle, true); + return; + } + } + base.WndProc (ref m); + } + + #endregion // Methods + + + #region Internal Methods + internal void OnDrawItemInternal (StatusBarDrawItemEventArgs e) + { + OnDrawItem (e); + } + + internal void UpdatePanel (StatusBarPanel panel) + { + if (panel.AutoSize == StatusBarPanelAutoSize.Contents) { + Update (); + return; + } + + Update (); + } + + internal void UpdatePanelContents (StatusBarPanel panel) + { + if (panel.AutoSize == StatusBarPanelAutoSize.Contents) { + Update (); + return; + } + + Update (); + } + + internal void Update () + { + CalcPanelSizes (); + Refresh (); + } + + private void DoPaint (PaintEventArgs pevent) + { + if (Width <= 0 || Height <= 0 || Visible == false) + return; + + Draw (pevent.Graphics, pevent.ClipRectangle); + } + + private void CalcPanelSizes () + { + if (panels == null || !show_panels) + return; + + if (Width == 0 || Height == 0) + return; + + int border = 2; + int gap = ThemeEngine.Current.StatusBarHorzGapWidth; + int taken = 0; + ArrayList springs = null; + + taken = border; + for (int i = 0; i < panels.Count; i++) { + StatusBarPanel p = panels [i]; + + if (p.AutoSize == StatusBarPanelAutoSize.None) { + taken += p.Width; + taken += gap; + continue; + } + if (p.AutoSize == StatusBarPanelAutoSize.Contents) { + int len = (int) (DeviceContext.MeasureString (p.Text, Font).Width + 0.5F); + p.SetWidth (len + 8); + taken += p.Width; + taken += gap; + continue; + } + if (p.AutoSize == StatusBarPanelAutoSize.Spring) { + if (springs == null) + springs = new ArrayList (); + springs.Add (p); + taken += gap; + continue; + } + } + + if (springs == null) + return; + + int spring_total = springs.Count; + int total_width = Width - taken - (SizingGrip ? ThemeEngine.Current.StatusBarSizeGripWidth : 0); + for (int i = 0; i < spring_total; i++) { + StatusBarPanel p = (StatusBarPanel) springs [i]; + int width = total_width / spring_total; + p.SetWidth (width >= p.MinWidth ? width : p.MinWidth); + } + + taken = border; + for (int i = 0; i < panels.Count; i++) { + StatusBarPanel p = panels [i]; + p.X = taken; + taken += p.Width + gap; + } + } + + private void Draw (Graphics dc, Rectangle clip) + { + ThemeEngine.Current.DrawStatusBar (dc, this.ClientRectangle, this); + } + #endregion // Internal Methods + + + #region Events + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler BackColorChanged; + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler BackgroundImageChanged; + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler ForeColorChanged; + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new event EventHandler ImeModeChanged; + + public event StatusBarDrawItemEventHandler DrawItem; + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public new event PaintEventHandler Paint; + public event StatusBarPanelClickEventHandler PanelClick; + #endregion // Events + + + #region Subclass StatusBarPanelCollection + public class StatusBarPanelCollection : IList, ICollection, IEnumerable { + #region Fields + private StatusBar owner; + private ArrayList panels; + #endregion // Fields + + #region Public Constructors + public StatusBarPanelCollection (StatusBar owner) + { + this.owner = owner; + } + + #endregion // Public Constructors + + #region Private & Internal Methods + private int AddInternal (StatusBarPanel p, bool refresh) { + if (p == null) + throw new ArgumentNullException ("value"); + if (panels == null) + panels = new ArrayList (); + + int res = panels.Add (p); + p.SetParent (owner); + + if (refresh) { + owner.CalcPanelSizes (); + owner.Refresh (); + } + + return res; + } + + #endregion // Private & Internal Methods + + #region Public Instance Properties + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public virtual int Count { + get { + if (panels == null) + return 0; + return panels.Count; + } + } + + public virtual bool IsReadOnly { + get { return false; } + } + + public virtual StatusBarPanel this [int index] { + get { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException ("index"); + return (StatusBarPanel) panels [index]; + } + set { + if (value == null) + throw new ArgumentNullException ("index"); + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException ("index"); + panels [index] = value; + } + } + + #endregion // Public Instance Properties + + #region Public Instance Methods + public virtual int Add (StatusBarPanel p) { + return AddInternal (p, true); + } + + public virtual StatusBarPanel Add (string text) { + StatusBarPanel res = new StatusBarPanel (); + res.Text = text; + Add (res); + return res; + } + + public virtual void AddRange (StatusBarPanel [] range) { + if (range == null) + throw new ArgumentNullException ("panels"); + if (range.Length == 0) + return; + if (panels == null) + panels = new ArrayList (range.Length); + + for (int i = 0; i < range.Length; i++) + AddInternal (range [i], false); + owner.Refresh (); + } + + public virtual void Clear () { + panels.Clear (); + + owner.Refresh (); + } + + public bool Contains (StatusBarPanel panel) { + return panels.Contains (panel); + } + + public virtual IEnumerator GetEnumerator () { + return panels.GetEnumerator (); + } + + public int IndexOf (StatusBarPanel panel) { + return panels.IndexOf (panel); + } + + public virtual void Insert (int index, StatusBarPanel value) { + if (value == null) + throw new ArgumentNullException ("value"); + if (index > Count) + throw new ArgumentOutOfRangeException ("index"); + // TODO: InvalidArgumentException for bad AutoSize values + // although it seems impossible to set it to a bad value + value.SetParent (owner); + panels [index] = value; + + owner.Refresh (); + } + + public virtual void Remove (StatusBarPanel panel) { + panels.Remove (panel); + } + + public virtual void RemoveAt (int index) { + panels.RemoveAt (index); + } + + #endregion // Public Instance Methods + + #region IList & ICollection Interfaces + bool ICollection.IsSynchronized { + get { return panels.IsSynchronized; } + } + + object ICollection.SyncRoot { + get { return panels.SyncRoot; } + } + + void ICollection.CopyTo (Array dest, int index) + { + panels.CopyTo (dest, index); + } + + + object IList.this [int index] { + get { return panels [index]; } + set { panels [index] = value; } + } + + int IList.Add (object value) { + return panels.Add (value); + } + + bool IList.Contains (object panel) { + return panels.Contains (panel); + } + + int IList.IndexOf (object panel) + { + return panels.IndexOf (panel); + } + + void IList.Insert (int index, object value) + { + panels.Insert (index, value); + } + + bool IList.IsFixedSize { + get { return false; } + } + + void IList.Remove (object value) + { + panels.Remove (value); + } + #endregion // IList & ICollection Interfaces + } + #endregion // Subclass StatusBarPanelCollection + } + +} + |