/// <summary> /// 鱼眼菜单 /// </summary> [DefaultProperty("Items")] [DefaultEvent("FisheyeItemClick")] [Description("鱼眼菜单")] public partial class FisheyeBarExt : Control { public delegate void EventHandler(object sender, FisheyeItemEventArgs e); private event EventHandler fisheyeItemClick; /// <summary> /// 鱼眼菜单单击事件 /// </summary> [Description("鱼眼菜单单击事件")] public event EventHandler FisheyeItemClick { add { this.fisheyeItemClick += value; } remove { this.fisheyeItemClick -= value; } } #region private bool itemTextShow = false; /// <summary> /// 是否显示选项文本 /// </summary> [DefaultValue(false)] [Description("是否显示选项文本")] public bool ItemTextShow { get { return this.itemTextShow; } set { if (this.itemTextShow == value) return; this.itemTextShow = value; this.InitializeItemLayout(); this.Invalidate(); } } private Font itemTextFont = new Font("宋体", 10); /// <summary> /// 选项文本字体 /// </summary> [DefaultValue(typeof(Font), "宋体, 10pt")] [Description("选项文本字体")] public Font ItemTextFont { get { return this.itemTextFont; } set { if (this.itemTextFont == value) return; this.itemTextFont = value; this.InitializeItemLayout(); this.Invalidate(); } } private Color itemTextColor = Color.White; /// <summary> /// 选项文本颜色 /// </summary> [DefaultValue(typeof(Color), "White")] [Description("选项文本颜色")] public Color ItemTextColor { get { return this.itemTextColor; } set { if (this.itemTextColor == value) return; this.itemTextColor = value; this.InitializeItemLayout(); this.Invalidate(); } } private float proportion = 0.6f; /// <summary> /// 鱼眼菜单选项默认缩放比例 /// </summary> [DefaultValue(0.6f)] [Description("鱼眼菜单选项默认缩放比例")] public float Proportion { get { return this.proportion; } set { if (this.proportion == value) return; this.proportion = value; this.InitializeItems(); this.InitializeItemLayout(); this.Invalidate(); } } private int itemWidth = 128; /// <summary> /// 选项宽度 /// </summary> [DefaultValue(128)] [Description("选项宽度")] public int ItemWidth { get { return this.itemWidth; } set { if (this.itemWidth == value) return; this.itemWidth = value; this.InitializeItemLayout(); this.Invalidate(); } } private int itemHeight = 128; /// <summary> /// 选项高度 /// </summary> [DefaultValue(128)] [Description("选项高度")] public int ItemHeight { get { return this.itemHeight; } set { if (this.itemHeight == value) return; this.itemHeight = value; this.InitializeItemLayout(); this.Invalidate(); } } private FisheyeLayoutType itemLayoutType = FisheyeLayoutType.Bottom; /// <summary> /// 选项布局类型 /// </summary> [DefaultValue(FisheyeLayoutType.Bottom)] [Description("选项布局类型")] public FisheyeLayoutType ItemLayoutType { get { return this.itemLayoutType; } set { if (this.itemLayoutType == value) return; this.itemLayoutType = value; this.InitializeItemLayout(); this.Invalidate(); } } private FisheyeBarExt.FisheyeItemCollection fisheyeItemCollection; /// <summary> /// 鱼眼菜单选项集合 /// </summary> [DefaultValue(null)] [Description("鱼眼菜单选项集合")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public FisheyeBarExt.FisheyeItemCollection Items { get { if (this.fisheyeItemCollection == null) this.fisheyeItemCollection = new FisheyeBarExt.FisheyeItemCollection(this); return this.fisheyeItemCollection; } } protected override Size DefaultSize { get { return new Size(600, 128); } } #endregion public FisheyeBarExt() { SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); InitializeComponent(); this.fisheyeItemCollection = new FisheyeItemCollection(this); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; RectangleF bounds_rect = g.ClipBounds; RectangleF rectf = new RectangleF(0, 0, this.ItemWidth, this.ItemHeight); SolidBrush itemtext_sb = new SolidBrush(this.ItemTextColor); for (int i = 0; i < this.fisheyeItemCollection.Count; i++) { if (this.Items[i].Image != null) { g.DrawImage(this.Items[i].Image, new RectangleF(this.fisheyeItemCollection[i].now_rectf.X, this.fisheyeItemCollection[i].now_rectf.Y, this.fisheyeItemCollection[i].now_rectf.Width, this.fisheyeItemCollection[i].now_rectf.Height)); } if (this.ItemTextShow) { SizeF itemtext_size = g.MeasureString(this.fisheyeItemCollection[i].Text, this.ItemTextFont); g.DrawString(this.fisheyeItemCollection[i].Text, this.ItemTextFont, itemtext_sb, this.fisheyeItemCollection[i].now_rectf.X + (this.fisheyeItemCollection[i].now_rectf.Width - itemtext_size.Width) / 2f, this.fisheyeItemCollection[i].now_rectf.Bottom - itemtext_size.Height); } } itemtext_sb.Dispose(); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); for (int i = 0; i < this.fisheyeItemCollection.Count; i++) { float distance = (float)Math.Sqrt(Math.Pow(Math.Abs(this.fisheyeItemCollection[i].now_centerpointf.X - e.X), 2) + Math.Pow(Math.Abs(this.fisheyeItemCollection[i].now_centerpointf.Y - e.Y), 2)); float p = 1 - distance / 240; if (p < this.Proportion) { p = this.Proportion; } this.fisheyeItemCollection[i].now_proportion = p; } this.InitializeItemLayout(); this.Invalidate(); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); for (int i = 0; i < this.fisheyeItemCollection.Count; i++) { this.InitializeItem(this.fisheyeItemCollection[i]); } this.InitializeItemLayout(); this.Invalidate(); } protected override void OnClick(EventArgs e) { base.OnClick(e); Point point = this.PointToClient(Control.MousePosition); if (this.fisheyeItemClick != null) { for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i].now_rectf.Contains(point)) { this.fisheyeItemClick(this, new FisheyeItemEventArgs() { Item = this.Items[i] }); break; } } } } protected override void OnResize(EventArgs e) { base.OnResize(e); this.InitializeItemLayout(); this.Invalidate(); } /// <summary> ///初始化鱼眼菜单选项 /// </summary> /// <param name="item"></param> private void InitializeItem(FisheyeItem item) { item.now_proportion = this.Proportion; } /// <summary> ///初始化鱼眼菜单选项集合 /// </summary> private void InitializeItems() { foreach (FisheyeItem item in this.fisheyeItemCollection) { item.now_proportion = this.Proportion; } } /// <summary> /// 初始化鱼眼菜单选项布局 /// </summary> private void InitializeItemLayout() { float sum = 0f; for (int i = 0; i < this.fisheyeItemCollection.Count; i++) { float now_width = this.ItemWidth * this.fisheyeItemCollection[i].now_proportion; float now_height = this.ItemHeight * this.fisheyeItemCollection[i].now_proportion; this.fisheyeItemCollection[i].now_rectf = new RectangleF(0f, 0f, now_width, now_height); switch (this.ItemLayoutType) { case FisheyeLayoutType.Top: case FisheyeLayoutType.Bottom: case FisheyeLayoutType.HorizontalCenter: { sum += now_width; break; } case FisheyeLayoutType.Left: case FisheyeLayoutType.Right: case FisheyeLayoutType.VerticalCenter: { sum += now_height; break; } } } for (int i = 0; i < this.fisheyeItemCollection.Count; i++) { float x = 0; float y = 0; switch (this.ItemLayoutType) { case FisheyeLayoutType.Bottom: { x = (i == 0) ? (this.ClientRectangle.Width - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Right; y = this.ClientRectangle.Height - this.fisheyeItemCollection[i].now_rectf.Height; break; } case FisheyeLayoutType.Top: { x = (i == 0) ? (this.ClientRectangle.Width - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Right; y = 0; break; } case FisheyeLayoutType.HorizontalCenter: { x = (i == 0) ? (this.ClientRectangle.Width - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Right; y = (this.ClientRectangle.Height - this.fisheyeItemCollection[i].now_rectf.Height) / 2; break; } case FisheyeLayoutType.Left: { x = 0; y = (i == 0) ? (this.ClientRectangle.Height - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Bottom; break; } case FisheyeLayoutType.Right: { x = this.ClientRectangle.Right - this.fisheyeItemCollection[i].now_rectf.Width; y = (i == 0) ? (this.ClientRectangle.Height - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Bottom; break; } case FisheyeLayoutType.VerticalCenter: { x = (this.ClientRectangle.Right - this.fisheyeItemCollection[i].now_rectf.Width) / 2; y = (i == 0) ? (this.ClientRectangle.Height - sum) / 2f : this.fisheyeItemCollection[i - 1].now_rectf.Bottom; break; } } this.fisheyeItemCollection[i].now_rectf = new RectangleF(x, y, this.fisheyeItemCollection[i].now_rectf.Width, this.fisheyeItemCollection[i].now_rectf.Height); this.fisheyeItemCollection[i].now_centerpointf = new PointF(this.fisheyeItemCollection[i].now_rectf.X + (this.fisheyeItemCollection[i].now_rectf.Width / 2), this.fisheyeItemCollection[i].now_rectf.Y + (this.fisheyeItemCollection[i].now_rectf.Height / 2)); } } protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } /// <summary> /// 鱼眼菜单选项集合 /// </summary> [Description("鱼眼菜单选项集合")] [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))] public sealed class FisheyeItemCollection : IList, ICollection, IEnumerable { private ArrayList fisheyeItemList = new ArrayList(); private FisheyeBarExt owner; public FisheyeItemCollection(FisheyeBarExt owner) { this.owner = owner; } #region IEnumerable public IEnumerator GetEnumerator() { FisheyeItem[] listArray = new FisheyeItem[this.fisheyeItemList.Count]; for (int index = 0; index < listArray.Length; ++index) listArray[index] = (FisheyeItem)this.fisheyeItemList[index]; return listArray.GetEnumerator(); } #endregion #region ICollection public void CopyTo(Array array, int index) { for (int i = 0; i < this.Count; i++) array.SetValue(this.fisheyeItemList[i], i + index); } public int Count { get { return this.fisheyeItemList.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return (object)this; } } #endregion #region IList public int Add(object value) { FisheyeItem fisheyeItem = (FisheyeItem)value; this.owner.InitializeItem(fisheyeItem); this.fisheyeItemList.Add(fisheyeItem); this.owner.InitializeItemLayout(); this.owner.Invalidate(); return this.Count - 1; } public void Clear() { this.fisheyeItemList.Clear(); this.owner.InitializeItemLayout(); this.owner.Invalidate(); } public bool Contains(object value) { return this.IndexOf(value) != -1; } public int IndexOf(object value) { return this.fisheyeItemList.IndexOf(value); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return false; } } public void Remove(object value) { if (!(value is FisheyeItem)) return; this.fisheyeItemList.Remove((FisheyeItem)value); this.owner.InitializeItemLayout(); this.owner.Invalidate(); } public void RemoveAt(int index) { this.fisheyeItemList.RemoveAt(index); this.owner.InitializeItemLayout(); this.owner.Invalidate(); } public FisheyeItem this[int index] { get { return (FisheyeItem)this.fisheyeItemList[index]; } set { this.fisheyeItemList[index] = (FisheyeItem)value; this.owner.InitializeItemLayout(); this.owner.Invalidate(); } } object IList.this[int index] { get { return (object)this.fisheyeItemList[index]; } set { this.fisheyeItemList[index] = (FisheyeItem)value; this.owner.InitializeItemLayout(); this.owner.Invalidate(); } } #endregion } } /// <summary> /// 鱼眼菜单选项 /// </summary> [Description("鱼眼菜单选项")] public class FisheyeItem { /// <summary> /// 预留信息 /// </summary> [Browsable(true)] [DefaultValue("")] [Description("预留信息")] public string Tag { get; set; } /// <summary> /// 选项图片 /// </summary> [Browsable(true)] [DefaultValue(null)] [Description("选项图片")] public Image Image { get; set; } /// <summary> /// 文本信息 /// </summary> [Browsable(true)] [DefaultValue("")] [Description("文本信息")] public string Text { get; set; } /// <summary> /// 当前选项大小比例 /// </summary> [Browsable(false)] public float now_proportion { get; set; } /// <summary> /// 当前选项rectf /// </summary> [Browsable(false)] public RectangleF now_rectf { get; set; } /// <summary> /// 当前选项rectf中心坐标 /// </summary> [Browsable(false)] public PointF now_centerpointf { get; set; } } /// <summary> /// 布局类型 /// </summary> [Description("布局类型")] public enum FisheyeLayoutType { /// <summary> /// 靠上 /// </summary> Top, /// <summary> /// /// </summary> Left, /// <summary> /// 靠下 /// </summary> Bottom, /// <summary> /// 靠右 /// </summary> Right, /// <summary> /// 横向居中 /// </summary> HorizontalCenter, /// <summary> /// 垂直居中 /// </summary> VerticalCenter } /// <summary> /// 鱼眼菜单单击事件参数 /// </summary> [Description("鱼眼菜单单击事件参数")] public class FisheyeItemEventArgs : EventArgs { /// <summary> /// 鱼眼菜单选项 /// </summary> [Description("鱼眼菜单选项")] public FisheyeItem Item { get; set; } }
源码下载:仿MAC鱼眼菜单栏控件.zip
原文地址:https://www.cnblogs.com/tlmbem/p/11314567.html
时间: 2024-10-07 11:38:38