1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453 |
- using Resources;
- using SmartCoalApplication.Base;
- using SmartCoalApplication.SystemLayer;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Windows.Forms.VisualStyles;
- namespace SmartCoalApplication.Core
- {
- public class ImageNameStrip : Control
- {
- public enum ItemPart
- {
- None,
- Image,
- CloseButton
- }
- public sealed class Item
- {
- private Rectangle rectangle;
- private PushButtonState imageRenderState;
- private Image image;
- private string name;
- private bool selected;
- private PushButtonState checkRenderState;
- private CheckState checkState;
- private PushButtonState closeRenderState;
- private bool dirty;
- private bool lockedDirtyValue;
- private int dirtyValueLockCount = 0;
- private object tag;
- public event EventHandler Changed;
- private void OnChanged()
- {
- if (Changed != null)
- {
- Changed(this, EventArgs.Empty);
- }
- }
- public Rectangle Rectangle
- {
- get
- {
- return this.rectangle;
- }
- set
- {
- this.rectangle = value;
- }
- }
- public string Name
- {
- get
- {
- return this.name;
- }
- set
- {
- this.name = value;
- OnChanged();
- }
- }
- public Image Image
- {
- get
- {
- return this.image;
- }
- set
- {
- this.image = value;
- OnChanged();
- }
- }
- public PushButtonState ImageRenderState
- {
- get
- {
- return this.imageRenderState;
- }
- set
- {
- if (this.imageRenderState != value)
- {
- this.imageRenderState = value;
- OnChanged();
- }
- }
- }
- public bool Selected
- {
- get
- {
- return this.selected;
- }
- set
- {
- if (this.selected != value)
- {
- this.selected = value;
- OnChanged();
- }
- }
- }
- public bool Dirty
- {
- get
- {
- if (this.dirtyValueLockCount > 0)
- {
- return this.lockedDirtyValue;
- }
- else
- {
- return this.dirty;
- }
- }
- set
- {
- if (this.dirty != value)
- {
- this.dirty = value;
- if (this.dirtyValueLockCount <= 0)
- {
- OnChanged();
- }
- }
- }
- }
- public void LockDirtyValue(bool forceValue)
- {
- ++this.dirtyValueLockCount;
- if (this.dirtyValueLockCount == 1)
- {
- this.lockedDirtyValue = forceValue;
- }
- }
- public void UnlockDirtyValue()
- {
- --this.dirtyValueLockCount;
- if (this.dirtyValueLockCount == 0)
- {
- OnChanged();
- }
- else if (this.dirtyValueLockCount < 0)
- {
- throw new InvalidOperationException("Calls to UnlockDirtyValue() must be matched by a preceding call to LockDirtyValue()");
- }
- }
- public bool Checked
- {
- get
- {
- return (CheckState == CheckState.Checked);
- }
- set
- {
- if (value)
- {
- CheckState = CheckState.Checked;
- }
- else
- {
- CheckState = CheckState.Unchecked;
- }
- }
- }
- public CheckState CheckState
- {
- get
- {
- return this.checkState;
- }
- set
- {
- if (this.checkState != value)
- {
- this.checkState = value;
- OnChanged();
- }
- }
- }
- public PushButtonState CheckRenderState
- {
- get
- {
- return this.checkRenderState;
- }
- set
- {
- if (this.checkRenderState != value)
- {
- this.checkRenderState = value;
- OnChanged();
- }
- }
- }
- public PushButtonState CloseRenderState
- {
- get
- {
- return this.closeRenderState;
- }
- set
- {
- if (this.closeRenderState != value)
- {
- this.closeRenderState = value;
- OnChanged();
- }
- }
- }
- public void SetPartRenderState(ItemPart itemPart, PushButtonState renderState)
- {
- switch (itemPart)
- {
- case ItemPart.None:
- break;
- case ItemPart.CloseButton:
- CloseRenderState = renderState;
- break;
- case ItemPart.Image:
- ImageRenderState = renderState;
- break;
- default:
- throw new InvalidEnumArgumentException();
- }
- }
- public object Tag
- {
- get
- {
- return this.tag;
- }
- set
- {
- this.tag = value;
- OnChanged();
- }
- }
- public void Update()
- {
- OnChanged();
- }
- public Item()
- {
- }
- public Item(Image image)
- {
- this.image = image;
- }
- }
- private bool managedFocus = false;
- private bool showScrollButtons = false;
- private ArrowButton leftScrollButton;
- private ArrowButton rightScrollButton;
- private int scrollOffset = 0;
- private bool showCloseButtons = false;
- private const int closeButtonLength = 13;
- private int imagePadding = 2;
- private int closeButtonPadding = 2;
- private int mouseOverIndex = -1;
- private ItemPart mouseOverItemPart = ItemPart.None;
- private bool mouseOverApplyRendering = false;
- private int mouseDownIndex = -1;
- private MouseButtons mouseDownButton = MouseButtons.None;
- private ItemPart mouseDownItemPart = ItemPart.None;
- private bool mouseDownApplyRendering = false;
- private bool drawDirtyOverlay = true;
- public bool DrawDirtyOverlay
- {
- get
- {
- return this.drawDirtyOverlay;
- }
- set
- {
- if (this.drawDirtyOverlay != value)
- {
- this.drawDirtyOverlay = value;
- Refresh();
- }
- }
- }
- // This is done as an optimization: otherwise we're getting flooded with MouseMove events
- // and constantly refreshing our rendering. So CPU usage goes to heck.
- private Point lastMouseMovePt = new Point(-32000, -32000);
- private List<Item> items = new List<Item>();
- protected ArrowButton LeftScrollButton
- {
- get
- {
- return this.leftScrollButton;
- }
- }
- protected ArrowButton RightScrollButton
- {
- get
- {
- return this.rightScrollButton;
- }
- }
- private void MouseStatesToItemStates()
- {
- UI.SuspendControlPainting(this);
- for (int i = 0; i < this.items.Count; ++i)
- {
- this.items[i].CheckRenderState = PushButtonState.Normal;
- this.items[i].CloseRenderState = PushButtonState.Normal;
- this.items[i].ImageRenderState = PushButtonState.Normal;
- this.items[i].Selected = false;
- }
- if (this.mouseDownApplyRendering)
- {
- if (this.mouseDownIndex < 0 || this.mouseDownIndex >= this.items.Count)
- {
- this.mouseDownApplyRendering = false;
- }
- else
- {
- this.items[this.mouseDownIndex].SetPartRenderState(this.mouseDownItemPart, PushButtonState.Pressed);
- this.items[this.mouseDownIndex].Selected = true;
- }
- }
- else if (this.mouseOverApplyRendering)
- {
- if (this.mouseOverIndex < 0 || this.mouseOverIndex >= this.items.Count)
- {
- this.mouseOverApplyRendering = false;
- }
- else
- {
- this.items[this.mouseOverIndex].SetPartRenderState(this.mouseOverItemPart, PushButtonState.Hot);
- this.items[this.mouseOverIndex].Selected = true;
- }
- }
- UI.ResumeControlPainting(this);
- Invalidate();
- }
- public ImageNameStrip()
- {
- SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
- SetStyle(ControlStyles.Selectable, false);
- DoubleBuffered = true;
- ResizeRedraw = true;
- InitializeComponent();
- }
- private void InitializeComponent()
- {
- this.leftScrollButton = new ArrowButton();
- this.rightScrollButton = new ArrowButton();
- SuspendLayout();
- //
- // leftScrollButton
- //
- this.leftScrollButton.Name = "leftScrollButton";
- this.leftScrollButton.ArrowDirection = ArrowDirection.Left;
- this.leftScrollButton.ArrowOutlineWidth = 1.0f;
- this.leftScrollButton.Click += new EventHandler(LeftScrollButton_Click);
- this.leftScrollButton.DrawWithGradient = true;
- //
- // rightScrollButton
- //
- this.rightScrollButton.Name = "rightScrollButton";
- this.rightScrollButton.ArrowDirection = ArrowDirection.Right;
- this.rightScrollButton.ArrowOutlineWidth = 1.0f;
- this.rightScrollButton.Click += new EventHandler(RightScrollButton_Click);
- this.rightScrollButton.DrawWithGradient = true;
- //
- // ImageStrip
- //
- this.Name = "ImageStrip";
- this.TabStop = false;
- this.Controls.Add(this.leftScrollButton);
- this.Controls.Add(this.rightScrollButton);
- ResumeLayout();
- PerformLayout();
- }
- public event EventHandler<EventArgs<ArrowDirection>> ScrollArrowClicked;
- protected virtual void OnScrollArrowClicked(ArrowDirection arrowDirection)
- {
- if (ScrollArrowClicked != null)
- {
- ScrollArrowClicked(this, new EventArgs<ArrowDirection>(arrowDirection));
- }
- }
- private void LeftScrollButton_Click(object sender, EventArgs e)
- {
- Focus();
- OnScrollArrowClicked(ArrowDirection.Left);
- }
- private void RightScrollButton_Click(object sender, EventArgs e)
- {
- Focus();
- OnScrollArrowClicked(ArrowDirection.Right);
- }
- /// <summary>
- /// This event is raised when this control wishes to relinquish focus.
- /// </summary>
- public event EventHandler RelinquishFocus;
- private void OnRelinquishFocus()
- {
- if (RelinquishFocus != null)
- {
- RelinquishFocus(this, EventArgs.Empty);
- }
- }
- /// <summary>
- /// Gets or sets whether the control manages focus.
- /// </summary>
- /// <remarks>
- /// If this is true, the toolstrip will capture focus when the mouse enters its client area. It will then
- /// relinquish focus (via the RelinquishFocus event) when the mouse leaves. It will not capture or
- /// attempt to relinquish focus if MenuStripEx.IsAnyMenuActive returns true.
- /// </remarks>
- public bool ManagedFocus
- {
- get
- {
- return this.managedFocus;
- }
- set
- {
- this.managedFocus = value;
- }
- }
- public void AddItem(Item newItem)
- {
- if (this.items.Contains(newItem))
- {
- throw new ArgumentException("newItem was already added to this control");
- }
- //在这里计算名称的宽度开始 zyh
- //需要保证名称不能为空
- Size textSize = TextRenderer.MeasureText(newItem.Name, new Font(SystemFonts.DefaultFont.Name, 10, FontStyle.Regular));
- newItem.Rectangle = new Rectangle(0, 0, textSize.Width + 10, ClientSize.Height);
- //在这里计算名称的宽度技术 zyh
- newItem.Changed += Item_Changed;
- this.items.Add(newItem);
- PerformLayout();
- Invalidate();
- }
- public void RemoveItem(Item item)
- {
- if (!this.items.Contains(item))
- {
- throw new ArgumentException("item was never added to this control");
- }
- item.Changed -= Item_Changed;
- this.items.Remove(item);
- PerformLayout();
- Invalidate();
- }
- public void ClearItems()
- {
- SuspendLayout();
- UI.SuspendControlPainting(this);
- while (this.items.Count > 0)
- {
- RemoveItem(this.items[this.items.Count - 1]);
- }
- UI.ResumeControlPainting(this);
- ResumeLayout(true);
- Invalidate();
- }
- private void Item_Changed(object sender, EventArgs e)
- {
- Invalidate();
- }
- /// <summary>
- /// Raised when an item is clicked on.
- /// </summary>
- /// <remarks>
- /// e.Data.First is a reference to the Item.
- /// e.Data.Second is the ItemPart.
- /// e.Data.Third is the MouseButtons that was used to click on the ItemPart.
- /// </remarks>
- public event EventHandler<EventArgs<Triple<Item, ItemPart, MouseButtons>>> ItemClicked;
- protected virtual void OnItemClicked(Item item, ItemPart itemPart, MouseButtons mouseButtons)
- {
- if (ItemClicked != null)
- {
- ItemClicked(this, new EventArgs<Triple<Item, ItemPart, MouseButtons>>(
- Triple.Create(item, itemPart, mouseButtons)));
- }
- }
- public void PerformItemClick(int itemIndex, ItemPart itemPart, MouseButtons mouseButtons)
- {
- PerformItemClick(this.items[itemIndex], itemPart, mouseButtons);
- }
- public void PerformItemClick(Item item, ItemPart itemPart, MouseButtons mouseButtons)
- {
- OnItemClicked(item, itemPart, mouseButtons);
- }
- public Item[] Items
- {
- get
- {
- return this.items.ToArray();
- }
- }
- public int ItemCount
- {
- get
- {
- return this.items.Count;
- }
- }
- public bool ShowScrollButtons
- {
- get
- {
- return this.showScrollButtons;
- }
- set
- {
- if (this.showScrollButtons != value)
- {
- this.showScrollButtons = value;
- PerformLayout();
- Invalidate(true);
- }
- }
- }
- public int MinScrollOffset
- {
- get
- {
- return 0;
- }
- }
- public int MaxScrollOffset
- {
- get
- {
- int itemsLength = GetAllItemWidth();//itemSize.Width * this.items.Count;
- int viewLength = itemsLength - ClientSize.Width;
- int maxScrollOffset = Math.Max(0, viewLength);
- return maxScrollOffset;
- }
- }
- public int ScrollOffset
- {
- get
- {
- return this.scrollOffset;
- }
- set
- {
- int clampedValue = Utility.Clamp(value, MinScrollOffset, MaxScrollOffset);
- if (this.scrollOffset != clampedValue)
- {
- this.scrollOffset = clampedValue;
- OnScrollOffsetChanged();
- Invalidate(true);
- }
- }
- }
- public event EventHandler ScrollOffsetChanged;
- protected virtual void OnScrollOffsetChanged()
- {
- PerformLayout();
- if (ScrollOffsetChanged != null)
- {
- ScrollOffsetChanged(this, EventArgs.Empty);
- }
- }
- /// <summary>
- /// 获取所有item的宽度和,
- /// 因为每个item和原来不一样了
- /// 原本item是等宽
- /// </summary>
- /// <returns></returns>
- public int GetAllItemWidth()
- {
- int widths = 0;
- for (int y = 0; y < items.Count; y++)
- {
- widths += items[y].Rectangle.Width;
- }
- return widths;
- }
- /// <summary>
- /// Gets the viewable area, in View coordinate space.
- /// </summary>
- public Rectangle ViewRectangle
- {
- get
- {
- Size itemSize = ItemSize;
- return new Rectangle(0, 0, GetAllItemWidth(), itemSize.Height);
- }
- }
- protected override void OnLayout(LayoutEventArgs levent)
- {
- int arrowWidth = UI.ScaleWidth(16);
- ScrollOffset = Utility.Clamp(this.scrollOffset, MinScrollOffset, MaxScrollOffset);
- // Determine arrow visibility / position
- this.leftScrollButton.Size = new Size(arrowWidth, ClientSize.Height);
- this.leftScrollButton.Location = new Point(0, 0);
- this.rightScrollButton.Size = new Size(arrowWidth, ClientSize.Height);
- this.rightScrollButton.Location = new Point(ClientSize.Width - this.rightScrollButton.Width, 0);
- bool showEitherButton = this.showScrollButtons && (this.ViewRectangle.Width > ClientRectangle.Width);
- bool showRightButton = (this.scrollOffset < MaxScrollOffset) && showEitherButton;
- bool showLeftButton = (this.scrollOffset > MinScrollOffset) && showEitherButton;
- this.rightScrollButton.Enabled = showRightButton;
- this.rightScrollButton.Visible = showRightButton;
- this.leftScrollButton.Enabled = showLeftButton;
- this.leftScrollButton.Visible = showLeftButton;
- base.OnLayout(levent);
- }
- public bool ShowCloseButtons
- {
- get
- {
- return this.showCloseButtons;
- }
- set
- {
- if (this.showCloseButtons != value)
- {
- this.showCloseButtons = value;
- PerformLayout();
- Invalidate();
- }
- }
- }
- public int PreferredMinClientWidth
- {
- get
- {
- if (this.items.Count == 0)
- {
- return 0;
- }
- int minWidth = ItemSize.Width;
- if (this.leftScrollButton.Visible || this.rightScrollButton.Visible)
- {
- minWidth += this.leftScrollButton.Width;
- minWidth += this.rightScrollButton.Width;
- }
- minWidth = Math.Min(minWidth, ViewRectangle.Width);
- return minWidth;
- }
- }
- public Size PreferredImageSize
- {
- get
- {
- Rectangle itemRect;
- MeasureItemPartRectangles(out itemRect, null);
- return new Size(itemRect.Width - imagePadding * 2, itemRect.Height - imagePadding * 2);
- }
- }
- public Size ItemSize
- {
- get
- {
- Rectangle itemRect;
- MeasureItemPartRectangles(out itemRect, null);
- return itemRect.Size;
- }
- }
- protected virtual void DrawItemBackground(Graphics g, Item item, Rectangle itemRect)
- {
- }
- protected virtual void DrawItemHighlight(
- Graphics g,
- Item item,
- Rectangle itemRect,
- Rectangle highlightRect)
- {
- Color backFillColor;
- Color outlineColor;
- Color textColor;
- if (item.Checked)
- {
- backFillColor = Color.FromArgb(192, SystemColors.Highlight);
- outlineColor = backFillColor;
- textColor = Color.White;
- }
- else if (item.Selected)
- {
- backFillColor = Color.FromArgb(64, SystemColors.HotTrack);
- outlineColor = Color.FromArgb(64, SystemColors.HotTrack);
- textColor = Color.Black;
- }
- else
- {
- backFillColor = Color.Transparent;
- outlineColor = Color.Transparent;
- textColor = Color.Black;
- }
- using (SolidBrush backFillBrush = new SolidBrush(backFillColor))
- {
- g.FillRectangle(backFillBrush, highlightRect);
- }
- using (Pen outlinePen = new Pen(outlineColor))
- {
- g.DrawRectangle(outlinePen, highlightRect.X, highlightRect.Y, highlightRect.Width - 1, highlightRect.Height - 1);
- }
- g.DrawString(item.Name, new Font(SystemFonts.DefaultFont.Name, 10, FontStyle.Regular), new SolidBrush(textColor), new PointF(itemRect.X + 5, itemRect.Y + 5));
- g.DrawLine(new Pen(Color.FromArgb(189, 189, 189)), itemRect.X + itemRect.Width - 1, itemRect.Y, itemRect.X + itemRect.Width - 1, itemRect.Y + 25);
- }
- protected virtual void DrawItemCloseButton(
- Graphics graphics,
- Item item,
- Rectangle itemRect,
- Rectangle closeButtonRect)
- {
- if (item.Checked && item.Selected)
- {
- const string resourceNamePrefix = "Images.ImageStrip.CloseButton.";
- const string resourceNameSuffix = ".png";
- string resourceNameInfix = item.CloseRenderState.ToString();
- string resourceName = resourceNamePrefix + resourceNameInfix + resourceNameSuffix;
- Image image = PdnResources.GetImageResource(resourceName).Reference;
- graphics.SmoothingMode = SmoothingMode.AntiAlias;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.DrawImage(image, closeButtonRect, new Rectangle(0, 0, image.Width, image.Width), GraphicsUnit.Pixel);
- }
- }
- protected virtual void DrawItemDirtyOverlay(
- Graphics graphics,
- Item item,
- Rectangle itemRect,
- Rectangle dirtyOverlayRect)
- {
- Color outerPenColor = Color.White;
- Color innerPenColor = Color.Orange;
- const int xInset = 2;
- int scaledXInset = UI.ScaleWidth(xInset);
- const float outerPenWidth = 4.0f;
- const float innerPenWidth = 2.0f;
- float scaledOuterPenWidth = UI.ScaleWidth(outerPenWidth);
- float scaledInnerPenWidth = UI.ScaleWidth(innerPenWidth);
- SmoothingMode oldSM = graphics.SmoothingMode;
- graphics.SmoothingMode = SmoothingMode.AntiAlias;
- int left = dirtyOverlayRect.Left + scaledXInset;
- int top = dirtyOverlayRect.Top + scaledXInset;
- int right = dirtyOverlayRect.Right - scaledXInset;
- int bottom = dirtyOverlayRect.Bottom - scaledXInset;
- float r = Math.Min((right - left) / 2.0f, (bottom - top) / 2.0f);
- PointF centerPt = new PointF((left + right) / 2.0f, (top + bottom) / 2.0f);
- float twoPiOver5 = (float)(Math.PI * 0.4);
- PointF a = new PointF(centerPt.X + r * (float)Math.Sin(twoPiOver5), centerPt.Y - r * (float)Math.Cos(twoPiOver5));
- PointF b = new PointF(centerPt.X + r * (float)Math.Sin(2 * twoPiOver5), centerPt.Y - r * (float)Math.Cos(2 * twoPiOver5));
- PointF c = new PointF(centerPt.X + r * (float)Math.Sin(3 * twoPiOver5), centerPt.Y - r * (float)Math.Cos(3 * twoPiOver5));
- PointF d = new PointF(centerPt.X + r * (float)Math.Sin(4 * twoPiOver5), centerPt.Y - r * (float)Math.Cos(4 * twoPiOver5));
- PointF e = new PointF(centerPt.X + r * (float)Math.Sin(5 * twoPiOver5), centerPt.Y - r * (float)Math.Cos(5 * twoPiOver5));
- PointF[] lines =
- new PointF[]
- {
- centerPt, a,
- centerPt, b,
- centerPt, c,
- centerPt, d,
- centerPt, e
- };
- using (Pen outerPen = new Pen(outerPenColor, scaledOuterPenWidth))
- {
- for (int i = 0; i < lines.Length; i += 2)
- {
- graphics.DrawLine(outerPen, lines[i], lines[i + 1]);
- }
- }
- using (Pen innerPen = new Pen(innerPenColor, scaledInnerPenWidth))
- {
- for (int i = 0; i < lines.Length; i += 2)
- {
- graphics.DrawLine(innerPen, lines[i], lines[i + 1]);
- }
- }
- graphics.SmoothingMode = oldSM;
- }
- private void DrawItem(Graphics graphics, Item item, Point offset)
- {
- Rectangle itemRect;
- Rectangle closeButtonRect;
- Rectangle dirtyOverlayRect;
- MeasureItemPartRectangles(
- item,
- out itemRect,
- out closeButtonRect,
- out dirtyOverlayRect);
- itemRect.X += offset.X;
- itemRect.Y += offset.Y;
- closeButtonRect.X += offset.X;
- closeButtonRect.Y += offset.Y;
- dirtyOverlayRect.X += offset.X;
- dirtyOverlayRect.Y += offset.Y;
- DrawItemBackground(graphics, item, itemRect);
- Rectangle highlightRect = itemRect;
- DrawItemHighlight(graphics, item, itemRect, highlightRect);
- if (this.showCloseButtons)
- {
- DrawItemCloseButton(graphics, item, itemRect, closeButtonRect);
- }
- if (this.drawDirtyOverlay && item.Dirty)
- {
- DrawItemDirtyOverlay(graphics, item, itemRect, dirtyOverlayRect);
- }
- }
- public Point ClientPointToViewPoint(Point clientPt)
- {
- int viewX = clientPt.X + this.scrollOffset;
- return new Point(viewX, clientPt.Y);
- }
- public Point ViewPointToClientPoint(Point viewPt)
- {
- int clientX = viewPt.X - this.scrollOffset;
- return new Point(clientX, viewPt.Y);
- }
- private Point ViewPointToItemPoint(int itemIndex, Point viewPt)
- {
- Rectangle itemRect = ItemIndexToItemViewRectangle(itemIndex);
- Point itemPt = new Point(viewPt.X - itemRect.X, viewPt.Y);
- return itemPt;
- }
- private Rectangle ItemIndexToItemViewRectangle(int itemIndex)
- {
- return items[itemIndex].Rectangle;
- }
- public int ViewPointToItemIndex(Point viewPt)
- {
- if (!ViewRectangle.Contains(viewPt))
- {
- return -1;
- }
- int index = -1;// viewPt.X / itemSize.Width;
- int width = 0;
- //循环所有item,判断是第几个
- for (int i = 0; i < items.Count; i++)
- {
- if (viewPt.X >= items[i].Rectangle.X + width &&
- viewPt.X < items[i].Rectangle.X + width + items[i].Rectangle.Width)
- {
- index = i;
- break;
- }
- width += items[i].Rectangle.Width;
- }
- return index;
- }
- private void MeasureItemPartRectangles(
- out Rectangle itemRect,
- Item item)
- {
- Size textSize = new Size(0, 0);
- if (item != null)
- textSize = TextRenderer.MeasureText(item.Name, new Font(SystemFonts.DefaultFont.Name, 10, FontStyle.Regular));
- itemRect = new Rectangle(
- 0,
- 0,
- textSize.Width == 0 ? 120 : textSize.Width + 10,//120,//ClientSize.Height
- ClientSize.Height);
- if (item != null)
- item.Rectangle = itemRect;
- }
- /// <summary>
- /// 计算位置,关闭按钮、修改标记
- /// </summary>
- /// <param name="item"></param>
- /// <param name="itemRect"></param>
- /// <param name="closeButtonRect"></param>
- /// <param name="dirtyOverlayRect"></param>
- private void MeasureItemPartRectangles(
- Item item,
- out Rectangle itemRect,
- out Rectangle closeButtonRect,
- out Rectangle dirtyOverlayRect)
- {
- MeasureItemPartRectangles(out itemRect, item);
- int scaledCloseButtonLength = UI.ScaleWidth(closeButtonLength);
- int scaledCloseButtonPadding = UI.ScaleWidth(closeButtonPadding);
- closeButtonRect = new Rectangle(
- itemRect.Width - scaledCloseButtonLength - scaledCloseButtonPadding,
- scaledCloseButtonPadding,
- scaledCloseButtonLength,
- scaledCloseButtonLength);
- dirtyOverlayRect = new Rectangle(
- scaledCloseButtonPadding,
- scaledCloseButtonPadding,
- scaledCloseButtonLength,
- scaledCloseButtonLength);
- }
- private ItemPart ItemPointToItemPart(Item item, Point pt)
- {
- Rectangle itemRect;
- Rectangle closeButtonRect;
- Rectangle dirtyOverlayRect;
- MeasureItemPartRectangles(
- item,
- out itemRect,
- out closeButtonRect,
- out dirtyOverlayRect);
- //判断是否是点击了关闭按钮
- int dhud = 0;
- int index = items.FindIndex(a => a == item);
- if (index > 0)
- {
- dhud = GetZeroToIndexWidth(index - 1);
- }
- closeButtonRect.X += dhud;
- if (closeButtonRect.Contains(pt))
- {
- return ItemPart.CloseButton;
- }
- int width = 0;
- bool isPart = false;
- //循环所有item,判断是第几个
- for (int i = 0; i < items.Count; i++)
- {
- if (pt.X >= items[i].Rectangle.X + width &&
- pt.X < items[i].Rectangle.X + width + items[i].Rectangle.Width)
- {
- isPart = true;
- break;
- }
- width += items[i].Rectangle.Width;
- }
- if (isPart)
- {
- return ItemPart.Image;
- }
- return ItemPart.None;
- }
- private int GetZeroToIndexWidth(int index)
- {
- int m = 0;
- for (int i = 0; i < items.Count; i++)
- {
- if (i <= index)
- m += items[i].Rectangle.Width;
- }
- return m;
- }
- private Rectangle ItemIndexToClientRect(int itemIndex)
- {
- Size itemSize = ItemSize;
- Rectangle clientRect = new Rectangle(
- GetZeroToIndexWidth(itemIndex),//itemSize.Width * itemIndex,
- 0,
- itemIndex < 0 ? itemSize.Width : items[itemIndex].Rectangle.Width,//itemSize.Width,
- itemSize.Height);
- return clientRect;
- }
- /// <summary>
- /// 计算偏移量
- /// </summary>
- /// <param name="itemIndex">下标</param>
- /// <param name="minOffset">最小偏移</param>
- /// <param name="maxOffset">最大偏移</param>
- /// <param name="minFullyShownOffset"></param>
- /// <param name="maxFullyShownOffset"></param>
- private void CalculateVisibleScrollOffsets(
- int itemIndex,
- out int minOffset,
- out int maxOffset,
- out int minFullyShownOffset,
- out int maxFullyShownOffset)
- {
- Rectangle itemClientRect = ItemIndexToClientRect(itemIndex);
- minOffset = itemClientRect.Left + 1 - ClientSize.Width;
- maxOffset = itemClientRect.Right - 1;
- minFullyShownOffset = itemClientRect.Right - ClientSize.Width;
- maxFullyShownOffset = itemClientRect.Left;
- if (this.leftScrollButton.Visible)
- {
- maxOffset -= this.leftScrollButton.Width;
- maxFullyShownOffset -= this.leftScrollButton.Width;
- }
- if (this.rightScrollButton.Visible)
- {
- minOffset += this.rightScrollButton.Width;
- minFullyShownOffset += this.rightScrollButton.Width;
- }
- }
- public Rectangle ScrolledViewRect
- {
- get
- {
- return new Rectangle(this.scrollOffset, 0, ClientSize.Width, ClientSize.Height);
- }
- }
- /// <summary>
- /// 判断item是否显示
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public bool IsItemVisible(int index)
- {
- Rectangle itemRect = ItemIndexToClientRect(index);
- Rectangle intersect = Rectangle.Intersect(itemRect, ScrolledViewRect);
- return (intersect.Width > 0 || intersect.Height > 0);
- }
- public bool IsItemFullyVisible(int index)
- {
- Rectangle itemRect = ItemIndexToClientRect(index);
- Rectangle svRect = ScrolledViewRect;
- if (this.leftScrollButton.Visible)
- {
- svRect.X += this.leftScrollButton.Width;
- svRect.Width -= this.leftScrollButton.Width;
- }
- if (this.rightScrollButton.Visible)
- {
- svRect.Width -= this.rightScrollButton.Width;
- }
- Rectangle intersect = Rectangle.Intersect(itemRect, svRect);
- return (intersect == itemRect);
- }
- public void EnsureItemFullyVisible(Item item)
- {
- int index = this.items.IndexOf(item);
- EnsureItemFullyVisible(index);
- }
- public void EnsureItemFullyVisible(int index)
- {
- if (IsItemFullyVisible(index))
- {
- return;
- }
- int minOffset;
- int maxOffset;
- int minFullyShownOffset;
- int maxFullyShownOffset;
- CalculateVisibleScrollOffsets(index, out minOffset, out maxOffset,
- out minFullyShownOffset, out maxFullyShownOffset);
- // Pick the offset that moves the image the fewest number of pixels
- int oldOffset = this.scrollOffset;
- int dxMin = Math.Abs(oldOffset - minFullyShownOffset);
- int dxMax = Math.Abs(oldOffset - maxFullyShownOffset);
- if (dxMin <= dxMax)
- {
- this.ScrollOffset = minFullyShownOffset;
- }
- else
- {
- this.ScrollOffset = maxFullyShownOffset;
- }
- }
- protected override void OnPaint(PaintEventArgs e)
- {
- if (UI.IsControlPaintingEnabled(this))
- {
- if (this.items != null && this.items.Count > 0)
- {
- Size itemSize = ItemSize;
- Rectangle firstItemRect = new Rectangle(-this.scrollOffset, 0, items[0].Rectangle.Width, itemSize.Height);
- for (int i = 0; i < this.items.Count; ++i)
- {
- //if (IsItemVisible(i)) //暂时注释掉,在观察
- {
- Point itemOffset = new Point(firstItemRect.X + GetZeroToIndexWidth(i - 1), firstItemRect.Y);
- //Point itemOffset = new Point(firstItemRect.X + itemSize.Width * i, firstItemRect.Y);
- DrawItem(e.Graphics, this.items[i], itemOffset);
- }
- }
- }
- }
- base.OnPaint(e);
- }
- protected override void OnMouseDown(MouseEventArgs e)
- {
- if (this.mouseDownButton == MouseButtons.None)
- {
- Point clientPt = new Point(e.X, e.Y);
- Point viewPt = ClientPointToViewPoint(clientPt);
- int itemIndex = ViewPointToItemIndex(viewPt);
- if (itemIndex >= 0 && itemIndex < this.items.Count)
- {
- Item item = this.items[itemIndex];
- Point itemPt = ViewPointToItemPoint(itemIndex, viewPt);
- ItemPart itemPart = ItemPointToItemPart(item, itemPt);
- if (itemPart == ItemPart.Image)
- {
- OnItemClicked(item, itemPart, e.Button);
- this.mouseDownApplyRendering = false;
- this.mouseOverIndex = itemIndex;
- this.mouseOverItemPart = itemPart;
- this.mouseOverApplyRendering = true;
- }
- else
- {
- this.mouseDownIndex = itemIndex;
- this.mouseDownItemPart = itemPart;
- this.mouseDownButton = e.Button;
- this.mouseDownApplyRendering = true;
- this.mouseOverApplyRendering = false;
- }
- MouseStatesToItemStates();
- Refresh();
- }
- }
- base.OnMouseDown(e);
- }
- protected override void OnMouseMove(MouseEventArgs e)
- {
- GetFocus();
- Point clientPt = new Point(e.X, e.Y);
- if (clientPt != this.lastMouseMovePt)
- {
- Point viewPt = ClientPointToViewPoint(clientPt);
- int itemIndex = ViewPointToItemIndex(viewPt);
- if (this.mouseDownButton == MouseButtons.None)
- {
- if (itemIndex >= 0 && itemIndex < this.items.Count)
- {
- Item item = this.items[itemIndex];
- Point itemPt = ViewPointToItemPoint(itemIndex, viewPt);
- ItemPart itemPart = ItemPointToItemPart(item, itemPt);
- this.mouseOverIndex = itemIndex;
- this.mouseOverItemPart = itemPart;
- this.mouseOverApplyRendering = true;
- }
- else
- {
- this.mouseOverApplyRendering = false;
- }
- }
- else
- {
- this.mouseOverApplyRendering = false;
- if (itemIndex != this.mouseDownIndex)
- {
- this.mouseDownApplyRendering = false;
- }
- else if (itemIndex < 0 || itemIndex >= this.items.Count)
- {
- this.mouseDownApplyRendering = false;
- }
- else
- {
- Item item = this.Items[itemIndex];
- Point itemPt = ViewPointToItemPoint(itemIndex, viewPt);
- ItemPart itemPart = ItemPointToItemPart(item, itemPt);
- if (itemPart != this.mouseDownItemPart)
- {
- this.mouseDownApplyRendering = false;
- }
- }
- }
- MouseStatesToItemStates();
- Refresh();
- }
- this.lastMouseMovePt = clientPt;
- base.OnMouseMove(e);
- }
- protected override void OnMouseUp(MouseEventArgs e)
- {
- bool raisedClickEvent = false;
- if (this.mouseDownButton == e.Button)
- {
- Point clientPt = new Point(e.X, e.Y);
- Point viewPt = ClientPointToViewPoint(clientPt);
- int itemIndex = ViewPointToItemIndex(viewPt);
- if (itemIndex >= 0 && itemIndex < this.items.Count)
- {
- Item item = this.items[itemIndex];
- Point itemPt = ViewPointToItemPoint(itemIndex, viewPt);
- ItemPart itemPart = ItemPointToItemPart(item, itemPt);
- if (itemIndex == this.mouseDownIndex && itemPart == this.mouseDownItemPart)
- {
- if (itemPart == ItemPart.CloseButton && !item.Checked)
- {
- // Can only close 'checked' images, just like how tab switching+closing works in IE7
- itemPart = ItemPart.Image;
- }
- OnItemClicked(item, itemPart, this.mouseDownButton);
- raisedClickEvent = true;
- }
- this.mouseOverApplyRendering = true;
- this.mouseOverItemPart = itemPart;
- this.mouseOverIndex = itemIndex;
- }
- this.mouseDownApplyRendering = false;
- this.mouseDownButton = MouseButtons.None;
- MouseStatesToItemStates();
- Refresh();
- }
- if (raisedClickEvent)
- {
- ForceMouseMove();
- }
- base.OnMouseUp(e);
- }
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- float count = (float)e.Delta / SystemInformation.MouseWheelScrollDelta;
- int pixels = GetAllItemWidth();//(int)(count * ItemSize.Width);
- int newSO = ScrollOffset - pixels;
- ScrollOffset = newSO;
- ForceMouseMove();
- base.OnMouseWheel(e);
- }
- private void ForceMouseMove()
- {
- Point clientPt = PointToClient(Control.MousePosition);
- this.lastMouseMovePt = new Point(this.lastMouseMovePt.X + 1, this.lastMouseMovePt.Y + 1);
- MouseEventArgs me = new MouseEventArgs(MouseButtons.None, 0, clientPt.X, clientPt.Y, 0);
- OnMouseMove(me);
- }
- protected override void OnMouseEnter(EventArgs e)
- {
- GetFocus();
- base.OnMouseEnter(e);
- }
- private void GetFocus()
- {
- if (this.managedFocus && !MenuStripEx.IsAnyMenuActive && UI.IsOurAppActive)
- {
- this.Focus();
- }
- }
- protected override void OnMouseLeave(EventArgs e)
- {
- this.mouseDownApplyRendering = false;
- this.mouseOverApplyRendering = false;
- MouseStatesToItemStates();
- Refresh();
- if (this.managedFocus && !MenuStripEx.IsAnyMenuActive && UI.IsOurAppActive)
- {
- OnRelinquishFocus();
- }
- base.OnMouseLeave(e);
- }
- }
- }
|