diff options
| author | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
|---|---|---|
| committer | MichaelTheShifter <[email protected]> | 2016-07-20 09:40:36 -0400 |
| commit | d40fed5ce2bc806a91245adb18039634eac13ed0 (patch) | |
| tree | f1d7168aee6db109ac2c738ad18c9db667a6ba69 /source/ShiftUI/Widgets/StatusStrip.cs | |
| parent | f1856e8ed30ed882229fd3fa2a4038122a5fb441 (diff) | |
| download | shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.gz shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.tar.bz2 shiftos-c--d40fed5ce2bc806a91245adb18039634eac13ed0.zip | |
Move ShiftUI source code to ShiftOS
This'll be a lot easier to work on.
Diffstat (limited to 'source/ShiftUI/Widgets/StatusStrip.cs')
| -rw-r--r-- | source/ShiftUI/Widgets/StatusStrip.cs | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/source/ShiftUI/Widgets/StatusStrip.cs b/source/ShiftUI/Widgets/StatusStrip.cs new file mode 100644 index 0000000..3ac3600 --- /dev/null +++ b/source/ShiftUI/Widgets/StatusStrip.cs @@ -0,0 +1,313 @@ +// +// StatusStrip.cs +// +// 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) 2006 Jonathan Pobst +// +// Authors: +// Jonathan Pobst ([email protected]) +// + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace ShiftUI +{ + [ClassInterface (ClassInterfaceType.AutoDispatch)] + [ComVisible (true)] + public class StatusStrip : ToolStrip + { + private bool sizing_grip; + + public StatusStrip () + { + SetStyle (Widgetstyles.ResizeRedraw, true); + + base.CanOverflow = false; + this.GripStyle = ToolStripGripStyle.Hidden; + base.LayoutStyle = ToolStripLayoutStyle.Table; + base.RenderMode = ToolStripRenderMode.System; + this.sizing_grip = true; + base.Stretch = true; + } + + #region Public Properties + [DefaultValue (DockStyle.Bottom)] + public override DockStyle Dock { + get { return base.Dock; } + set { base.Dock = value; } + } + + [Browsable (false)] + [DefaultValue (false)] + public new bool CanOverflow { + get { return base.CanOverflow; } + set { base.CanOverflow = value; } + } + + [DefaultValue (ToolStripGripStyle.Hidden)] + public new ToolStripGripStyle GripStyle { + get { return base.GripStyle; } + set { base.GripStyle = value; } + } + + [DefaultValue (ToolStripLayoutStyle.Table)] + public new ToolStripLayoutStyle LayoutStyle { + get { return base.LayoutStyle; } + set { base.LayoutStyle = value; } + } + + [Browsable (false)] + public new Padding Padding { + get { return base.Padding; } + set { base.Padding = value; } + } + + [DefaultValue (false)] + public new bool ShowItemToolTips { + get { return base.ShowItemToolTips; } + set { base.ShowItemToolTips = value; } + } + + [Browsable (false)] + public Rectangle SizeGripBounds { + get { return new Rectangle (this.Width - 12, 0, 12, this.Height); } + } + + [DefaultValue (true)] + public bool SizingGrip { + get { return this.sizing_grip; } + set { this.sizing_grip = value; } + } + + [DefaultValue (true)] + public new bool Stretch { + get { return base.Stretch; } + set { base.Stretch = value; } + } + #endregion + + #region Protected Properties + protected override DockStyle DefaultDock { + get { return DockStyle.Bottom; } + } + + protected override Padding DefaultPadding { + get { return new Padding (1, 0, 14, 0); } + } + + protected override bool DefaultShowItemToolTips { + get { return false; } + } + + protected override Size DefaultSize { + get { return new Size (200, 22); } + } + #endregion + + #region Protected Methods + protected override AccessibleObject CreateAccessibilityInstance () + { + return new StatusStripAccessibleObject (); + } + + protected internal override ToolStripItem CreateDefaultItem (string text, Image image, EventHandler onClick) + { + if (text == "-") + return new ToolStripSeparator (); + + return new ToolStripLabel (text, image, false, onClick); + } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + } + + protected override void OnLayout (LayoutEventArgs levent) + { + this.OnSpringTableLayoutCore (); + this.Invalidate (); + } + + protected override void OnPaintBackground (PaintEventArgs e) + { + base.OnPaintBackground (e); + + if (this.sizing_grip) + this.Renderer.DrawStatusStripSizingGrip (new ToolStripRenderEventArgs (e.Graphics, this, Bounds, SystemColors.Control)); + } + + protected virtual void OnSpringTableLayoutCore () + { + if (!this.Created) + return; + + ToolStripItemOverflow[] overflow = new ToolStripItemOverflow[this.Items.Count]; + ToolStripItemPlacement[] placement = new ToolStripItemPlacement[this.Items.Count]; + Size proposedSize = new Size (0, Bounds.Height); + int[] widths = new int[this.Items.Count]; + int total_width = 0; + int toolstrip_width = DisplayRectangle.Width; + int i = 0; + int spring_count = 0; + + foreach (ToolStripItem tsi in this.Items) { + overflow[i] = tsi.Overflow; + widths[i] = tsi.GetPreferredSize (proposedSize).Width + tsi.Margin.Horizontal; + placement[i] = tsi.Overflow == ToolStripItemOverflow.Always ? ToolStripItemPlacement.None : ToolStripItemPlacement.Main; + placement[i] = tsi.Available && tsi.InternalVisible ? placement[i] : ToolStripItemPlacement.None; + total_width += placement[i] == ToolStripItemPlacement.Main ? widths[i] : 0; + if (tsi is ToolStripStatusLabel && (tsi as ToolStripStatusLabel).Spring) + spring_count++; + + i++; + } + + while (total_width > toolstrip_width) { + bool removed_one = false; + + // Start at the right, removing Overflow.AsNeeded first + for (int j = widths.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.AsNeeded && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.None; + total_width -= widths[j]; + removed_one = true; + break; + } + + // If we didn't remove any AsNeeded ones, we have to start removing Never ones + // These are not put on the Overflow, they are simply not shown + if (!removed_one) + for (int j = widths.Length - 1; j >= 0; j--) + if (overflow[j] == ToolStripItemOverflow.Never && placement[j] == ToolStripItemPlacement.Main) { + placement[j] = ToolStripItemPlacement.None; + total_width -= widths[j]; + removed_one = true; + break; + } + + // There's nothing left to remove, break or we will loop forever + if (!removed_one) + break; + } + + if (spring_count > 0) { + int per_item = (toolstrip_width - total_width) / spring_count; + i = 0; + + foreach (ToolStripItem tsi in this.Items) { + if (tsi is ToolStripStatusLabel && (tsi as ToolStripStatusLabel).Spring) + widths[i] += per_item; + + i++; + } + } + + i = 0; + Point layout_pointer = new Point (this.DisplayRectangle.Left, this.DisplayRectangle.Top); + int button_height = this.DisplayRectangle.Height; + + // Now we should know where everything goes, so lay everything out + foreach (ToolStripItem tsi in this.Items) { + tsi.SetPlacement (placement[i]); + + if (placement[i] == ToolStripItemPlacement.Main) { + tsi.SetBounds (new Rectangle (layout_pointer.X + tsi.Margin.Left, layout_pointer.Y + tsi.Margin.Top, widths[i] - tsi.Margin.Horizontal, button_height - tsi.Margin.Vertical)); + layout_pointer.X += widths[i]; + } + + i++; + } + + this.SetDisplayedItems (); + } + + protected override void SetDisplayedItems () + { + // Only clean the internal collection, without modifying Owner/Parent on items. + this.displayed_items.ClearInternal (); + + foreach (ToolStripItem tsi in this.Items) + if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) { + this.displayed_items.AddNoOwnerOrLayout (tsi); + tsi.Parent = this; + } + } + + protected override void WndProc (ref Message m) + { + switch ((Msg)m.Msg) { + // If the mouse is over the size grip, change the cursor + case Msg.WM_MOUSEMOVE: { + if (FromParamToMouseButtons ((int) m.WParam.ToInt32()) == MouseButtons.None) { + Point p = new Point (LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ())); + + if (this.SizingGrip && this.SizeGripBounds.Contains (p)) { + this.Cursor = Cursors.SizeNWSE; + return; + } else + this.Cursor = Cursors.Default; + } + + break; + } + // If the left mouse button is pushed over the size grip, + // send the WM a message to begin a window resize operation + case Msg.WM_LBUTTONDOWN: { + Point p = new Point (LowOrder ((int)m.LParam.ToInt32 ()), HighOrder ((int)m.LParam.ToInt32 ())); + Form form = FindForm (); + + if (this.SizingGrip && this.SizeGripBounds.Contains (p)) { + // For top level forms it's not enoug to send a NCLBUTTONDOWN message, so + // we make a direct call to our XplatUI engine. + if (!form.IsMdiChild) + XplatUI.BeginMoveResize (form.Handle); + + XplatUI.SendMessage (form.Handle, Msg.WM_NCLBUTTONDOWN, (IntPtr) HitTest.HTBOTTOMRIGHT, IntPtr.Zero); + return; + } + + break; + } + } + + base.WndProc (ref m); + } + #endregion + + #region Public Events + [Browsable (false)] + public new event EventHandler PaddingChanged { + add { base.PaddingChanged += value; } + remove { base.PaddingChanged -= value; } + } + #endregion + + #region StatusStripAccessibleObject + private class StatusStripAccessibleObject : AccessibleObject + { + } + #endregion + } +} |
