123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554 |
- 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 IBottomNameStrip : Control
- {
- public enum ItemPart
- {
- None,
- Image,
- CloseButton
- }
- public sealed class Item
- {
- private Rectangle rectangle;
- private PushButtonState imageRenderState;
- /// <summary>
- /// 图片
- /// </summary>
- private Image image;
- /// <summary>
- ///
- /// </summary>
- private string name;
- /// <summary>
- /// 文字颜色
- /// </summary>
- private Color nColor;
- private bool selected;
- private PushButtonState checkRenderState;
- private CheckState checkState;
- private PushButtonState closeRenderState;
- private bool dirty;
- private bool lockedDirtyValue;
- private int dirtyValueLockCount = 0;
- /// <summary>
- /// Tag
- /// </summary>
- private object tag;
- public event EventHandler Changed;
- private void OnChanged()
- {
- if (Changed != null)
- {
- Changed(this, EventArgs.Empty);
- }
- }
- /// <summary>
- /// checkbox的被选中/取消选中事件
- /// 实际上没有用checkbox,而是自己画的,自己控制的逻辑
- /// </summary>
- public event EventHandler CheckChanged;
- private void OnCheckChanged()
- {
- if (CheckChanged != null)
- {
- CheckChanged(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 Color NColor
- {
- get
- {
- return this.nColor;
- }
- set
- {
- this.nColor = 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();
- OnCheckChanged();
- }
- }
- }
- 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 = true;//false;
- private bool allowMultiChoise = true;//模式是多选模式
- private ArrowButton leftScrollButton;
- private ArrowButton rightScrollButton;
- private int scrollOffset = 0;
- private bool showCheckButtons = false;
- 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 showCheckedColor = true;
- private bool drawDirtyOverlay = true;
- public bool ShowCheckedColor
- {
- get
- {
- return this.showCheckedColor;
- }
- set
- {
- if (this.showCheckedColor != value)
- {
- this.showCheckedColor = value;
- Refresh();
- }
- }
- }
- 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);
- public 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 IBottomNameStrip()
- {
- 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.drawTransparentBackColor = false;
- 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.drawTransparentBackColor = false;
- 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 + 33, 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 AllowMultiChoise
- {
- get
- {
- return this.allowMultiChoise;
- }
- set
- {
- if (this.allowMultiChoise != value)
- {
- this.allowMultiChoise = 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 ShowCheckButtons
- {
- get
- {
- return this.showCheckButtons;
- }
- set
- {
- if (this.showCheckButtons != value)
- {
- this.showCheckButtons = value;
- PerformLayout();
- Invalidate();
- }
- }
- }
- 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 graphics, Item item, Rectangle itemRect)
- {
- }
- protected virtual void DrawItemHighlight(
- Graphics graphics,
- Item item,
- Rectangle itemRect,
- Rectangle highlightRect)
- {
- Color backFillColor;
- Color outlineColor;
- Color textColor;
- if (item.Checked && this.showCheckedColor)
- {
- 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))
- {
- graphics.FillRectangle(backFillBrush, highlightRect);
- }
- using (Pen outlinePen = new Pen(outlineColor))
- {
- graphics.DrawRectangle(outlinePen, highlightRect.X, highlightRect.Y, highlightRect.Width - 1, highlightRect.Height - 1);
- }
- CheckBoxRenderer.DrawCheckBox(graphics, new Point(itemRect.X + 10, itemRect.Y + 10), (item.Checked && !this.showCheckedColor) ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal);
- graphics.DrawString(item.Name, new Font(SystemFonts.DefaultFont.Name, 10, FontStyle.Regular), new SolidBrush(item.NColor != null ? item.NColor : textColor), new PointF(itemRect.X + 24, itemRect.Y + 10));
- graphics.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;
- ImageResource imageResource = PdnResources.GetImageResource(resourceName);
- Image image = imageResource.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 g, Item item, Point offset)
- {
- Rectangle itemRect;
- //Rectangle checkButtonRect;
- 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(g, item, itemRect);
- Rectangle highlightRect = itemRect;
- DrawItemHighlight(g, item, itemRect, highlightRect);
- if (this.showCloseButtons)
- {
- DrawItemCloseButton(g, item, itemRect, closeButtonRect);
- }
- if (this.drawDirtyOverlay && item.Dirty)
- {
- DrawItemDirtyOverlay(g, item, itemRect, dirtyOverlayRect);
- }
- }
- public Point ClientPointToViewPoint(Point clientPt)
- {
- int viewX = clientPt.X + this.scrollOffset;
- return new Point(viewX, clientPt.Y);
- }
- public Rectangle ClientRectangleToViewRectangle(Rectangle clientRect)
- {
- Point viewPt = ClientPointToViewPoint(clientRect.Location);
- return new Rectangle(viewPt, clientRect.Size);
- }
- public Point ViewPointToClientPoint(Point viewPt)
- {
- int clientX = viewPt.X - this.scrollOffset;
- return new Point(clientX, viewPt.Y);
- }
- public Rectangle ViewRectangleToClientRectangle(Rectangle viewRect)
- {
- Point clientPt = ViewPointToClientPoint(viewRect.Location);
- return new Rectangle(clientPt, viewRect.Size);
- }
- 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;
- //Size itemSize = ItemSize;
- //return new Rectangle(itemSize.Width * itemIndex, itemSize.Height, itemSize.Width, itemSize.Height);
- }
- 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)
- {
- //CheckBoxRenderer
- Size textSize = new Size(0, 0);
- if (item != null)
- textSize = /*CheckBoxRenderer*/TextRenderer.MeasureText(item.Name, new Font(SystemFonts.DefaultFont.Name, 10, FontStyle.Regular));
- itemRect = new Rectangle(
- 0,
- 0,
- textSize.Width == 0 ? 120 : textSize.Width + 33,//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;
- }
- }
- 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);
- }
- private void GetFocus()
- {
- if (this.managedFocus && !MenuStripEx.IsAnyMenuActive && UI.IsOurAppActive)
- {
- this.Focus();
- }
- }
- #region 绘制、鼠标进入、离开、按下、移动、抬起、滚轮事件
- 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);
- }
- protected override void OnMouseEnter(EventArgs e)
- {
- GetFocus();
- base.OnMouseEnter(e);
- }
- 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);
- }
- #endregion
- }
- }
|