private static Brush GetArrowButtonBackgroundBrush(ScrollBarArrowButtonStyle Style, Hotness Hotness, out Brush TriangleBrush) { switch (Hotness) { case Hotness.VeryHot: TriangleBrush = SystemBrushes.ButtonHighlight; return(SystemBrushes.ControlText); case Hotness.Warm: TriangleBrush = SystemBrushes.ControlText; return(SystemBrushes.ButtonHighlight); default: TriangleBrush = SystemBrushes.ControlText; return(Style == ScrollBarArrowButtonStyle.FlatBorderless ? SystemBrushes.ScrollBar : SystemBrushes.ButtonFace); } }
/// <summary> /// Call this in <see cref="Control.OnPaint"/> with the most recent known values. /// </summary> public void Paint(Graphics g, ref LayoutInfo LayoutInfo, ScrollBarArrowButtonStyle ArrowButtonStyle) { this.LastLayoutInfo = LayoutInfo; var Metrics = this.GetControlMetrics(); // NOTE: We can't just check the current mouse position here. Even if the mouse is actually hovering over an element, it might not be in the hover state if another // control has capture. We have to do this with the last known mouse position, set in the mouse events after all. var HoveredItem = this.UpdateHoveredItem(ref Metrics, InvalidateIfChanged: false); //Debug.WriteLine($"paint ({frame++})"); var OldSmoothingMode = g.SmoothingMode; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; var OldTransform = g.Transform; g.TranslateTransform(LayoutInfo.Bounds.Left, LayoutInfo.Bounds.Top); // Track (above thumb) { Brush Brush = GetTrackBrush(this.GetItemHotness(HoveredItem, ScrollBarElement.TrackAboveThumb)); if (LayoutInfo.Horizontal) { g.FillRectangle(Brush, Metrics.TrackStart, 0, Metrics.ThumbStart - Metrics.TrackStart, LayoutInfo.Bounds.Height); } else { g.FillRectangle(Brush, 0, Metrics.TrackStart, LayoutInfo.Bounds.Width, Metrics.ThumbStart - Metrics.TrackStart); } } // Track (below thumb) { Brush Brush = GetTrackBrush(this.GetItemHotness(HoveredItem, ScrollBarElement.TrackBelowThumb)); if (LayoutInfo.Horizontal) { g.FillRectangle(Brush, Metrics.ThumbStart + Metrics.ThumbSize, 0, Metrics.BottomButtonStart - (Metrics.ThumbStart + Metrics.ThumbSize), LayoutInfo.Bounds.Height); } else { g.FillRectangle(Brush, 0, Metrics.ThumbStart + Metrics.ThumbSize, LayoutInfo.Bounds.Width, Metrics.BottomButtonStart - (Metrics.ThumbStart + Metrics.ThumbSize)); } } // Thumb { Brush Brush; switch (this.GetItemHotness(HoveredItem, ScrollBarElement.Thumb, CanBeHotWithoutHover: true)) { case Hotness.VeryHot: Brush = SystemBrushes.ButtonHighlight; break; case Hotness.Warm: Brush = SystemBrushes.ControlDarkDark; break; default: Brush = SystemBrushes.ControlDark; break; } if (LayoutInfo.Horizontal) { g.FillRectangle(Brush, Metrics.ThumbStart, 0, Metrics.ThumbSize, LayoutInfo.Bounds.Height); } else { g.FillRectangle(Brush, 0, Metrics.ThumbStart, LayoutInfo.Bounds.Width, Metrics.ThumbSize); } } float TriangleScale = (LayoutInfo.Horizontal ? LayoutInfo.Bounds.Height : LayoutInfo.Bounds.Width) / 4.0f; // Top Button { Brush BackgroundBrush = GetArrowButtonBackgroundBrush(ArrowButtonStyle, this.GetItemHotness(HoveredItem, ScrollBarElement.TopButton), out Brush TriangleBrush); Rectangle Rect; if (LayoutInfo.Horizontal) { Rect = new Rectangle(0, 0, Metrics.TrackStart, LayoutInfo.Bounds.Height); } else { Rect = new Rectangle(0, 0, LayoutInfo.Bounds.Width, Metrics.TrackStart - 0); // "0" stands for top button start } g.FillRectangle(BackgroundBrush, Rect); if (ArrowButtonStyle != ScrollBarArrowButtonStyle.FlatBorderless) { g.DrawRectangle(SystemPens.ControlText, Rect.X + 0.5f, Rect.Y + 0.5f, Rect.Width - 1.0f, Rect.Height - 1.0f); } this.DrawTriangle(g, new PointF(Rect.Width / 2.0f + Rect.X, Rect.Height / 2.0f + Rect.Y), TriangleScale, TriangleBrush, LayoutInfo.Horizontal); } // Bottom Button { Brush BackgroundBrush = GetArrowButtonBackgroundBrush(ArrowButtonStyle, this.GetItemHotness(HoveredItem, ScrollBarElement.BottomButton), out Brush TriangleBrush); Rectangle Rect; if (LayoutInfo.Horizontal) { Rect = new Rectangle(Metrics.BottomButtonStart, 0, LayoutInfo.Bounds.Width - Metrics.BottomButtonStart, LayoutInfo.Bounds.Height); } else { Rect = new Rectangle(0, Metrics.BottomButtonStart, LayoutInfo.Bounds.Width, LayoutInfo.Bounds.Height - Metrics.BottomButtonStart); } g.FillRectangle(BackgroundBrush, Rect); if (ArrowButtonStyle != ScrollBarArrowButtonStyle.FlatBorderless) { g.DrawRectangle(SystemPens.ControlText, Rect.X + 0.5f, Rect.Y + 0.5f, Rect.Width - 1.0f, Rect.Height - 1.0f); } this.DrawTriangle(g, new PointF(Rect.Width / 2.0f + Rect.X, Rect.Height / 2.0f + Rect.Y), -TriangleScale, TriangleBrush, LayoutInfo.Horizontal); } // Restore all state g.Transform = OldTransform; g.SmoothingMode = OldSmoothingMode; //TextRenderer.DrawText(g, this.CapturedItem + Environment.NewLine + this.HoveredItem + Environment.NewLine + this.IsCapturedItemActive, new Font("Microsoft Sans Serif", 9.75f), new Point(0, 0), Color.Red); }