private static IDisposable DrawBackExpert(Rectangle drawRect, Color color1, Color color2, VisualOrientation orientation, Graphics g, IDisposable memento, bool total, bool tracking) { // Cannot draw a zero length rectangle if ((drawRect.Width > 0) && (drawRect.Height > 0)) { var generate = true; MementoBackExpertChecked cache; // Access a cache instance and decide if cache resources need generating if (memento is MementoBackExpertChecked expertChecked) { cache = expertChecked; generate = !cache.UseCachedValues(drawRect, color1, color2, orientation); } else { memento?.Dispose(); cache = new MementoBackExpertChecked(drawRect, color1, color2, orientation); memento = cache; } // Do we need to generate the contents of the cache? if (generate) { // Dispose of existing values cache.Dispose(); // If not drawing total area... if (!total) { // Update to draw the inside area instead drawRect.Inflate(-1, -1); cache.drawRect = drawRect; cache.clipPath = new GraphicsPath(); cache.clipPath.AddLine(drawRect.X + 1, drawRect.Y, drawRect.Right - 1, drawRect.Y); cache.clipPath.AddLine(drawRect.Right - 1, drawRect.Y, drawRect.Right, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Right, drawRect.Y + 1, drawRect.Right, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Right, drawRect.Bottom - 2, drawRect.Right - 2, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Right - 2, drawRect.Bottom, drawRect.Left + 1, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Left + 1, drawRect.Bottom, drawRect.Left, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Left, drawRect.Bottom - 2, drawRect.Left, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Left, drawRect.Y + 1, drawRect.X + 1, drawRect.Y); } else { cache.clipPath = new GraphicsPath(); cache.clipPath.AddRectangle(drawRect); } // Create rectangle that covers the enter area RectangleF gradientRect = new(drawRect.X - 1, drawRect.Y - 1, drawRect.Width + 2, drawRect.Height + 2); // Cannot draw a zero length rectangle if ((gradientRect.Width > 0) && (gradientRect.Height > 0)) { // Draw entire area in a gradient color effect cache.entireBrush = new LinearGradientBrush(gradientRect, CommonHelper.WhitenColor(color1, 0.92f, 0.92f, 0.92f), color1, AngleFromOrientation(orientation)) { Blend = _rounded1Blend }; } RectangleF ellipseRect; PointF ellipseCenter; var ellipseHeight = Math.Max(1, drawRect.Height / 4); var ellipseWidth = Math.Max(1, tracking ? drawRect.Width : drawRect.Width / 4); // Ellipse is based on the orientation switch (orientation) { default: case VisualOrientation.Top: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Bottom - ellipseHeight, drawRect.Width + (ellipseWidth * 2), ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Bottom); break; case VisualOrientation.Bottom: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, drawRect.Width + (ellipseWidth * 2), ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Top); break; case VisualOrientation.Left: ellipseRect = new RectangleF(drawRect.Right - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + (ellipseHeight * 2)); ellipseCenter = new PointF(ellipseRect.Right, ellipseRect.Top + (ellipseRect.Height / 2)); break; case VisualOrientation.Right: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + (ellipseHeight * 2)); ellipseCenter = new PointF(ellipseRect.Left, ellipseRect.Top + (ellipseRect.Height / 2)); break; } cache.ellipsePath = new GraphicsPath(); cache.ellipsePath.AddEllipse(ellipseRect); cache.insideLighten = new PathGradientBrush(cache.ellipsePath) { CenterPoint = ellipseCenter, CenterColor = color2, Blend = _rounded2Blend, SurroundColors = new[] { Color.Transparent } }; } if (cache.entireBrush != null) { using Clipping clip = new(g, cache.clipPath); g.FillRectangle(cache.entireBrush, cache.drawRect); g.FillPath(cache.insideLighten, cache.ellipsePath); } } return(memento); }
private static IDisposable DrawBackExpert(Rectangle drawRect, Color color1, Color color2, VisualOrientation orientation, Graphics g, IDisposable memento, bool total, bool tracking) { // Cannot draw a zero length rectangle if ((drawRect.Width > 0) && (drawRect.Height > 0)) { bool generate = true; MementoBackExpertChecked cache; // Access a cache instance and decide if cache resources need generating if ((memento == null) || !(memento is MementoBackExpertChecked)) { if (memento != null) memento.Dispose(); cache = new MementoBackExpertChecked(drawRect, color1, color2, orientation); memento = cache; } else { cache = (MementoBackExpertChecked)memento; generate = !cache.UseCachedValues(drawRect, color1, color2, orientation); } // Do we need to generate the contents of the cache? if (generate) { // Dispose of existing values cache.Dispose(); // If not drawing total area... if (!total) { // Update to draw the inside area instead drawRect.Inflate(-1, -1); cache.drawRect = drawRect; cache.clipPath = new GraphicsPath(); cache.clipPath.AddLine(drawRect.X + 1, drawRect.Y, drawRect.Right - 1, drawRect.Y); cache.clipPath.AddLine(drawRect.Right - 1, drawRect.Y, drawRect.Right, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Right, drawRect.Y + 1, drawRect.Right, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Right, drawRect.Bottom - 2, drawRect.Right - 2, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Right - 2, drawRect.Bottom, drawRect.Left + 1, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Left + 1, drawRect.Bottom, drawRect.Left, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Left, drawRect.Bottom - 2, drawRect.Left, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Left, drawRect.Y + 1, drawRect.X + 1, drawRect.Y); } else { cache.clipPath = new GraphicsPath(); cache.clipPath.AddRectangle(drawRect); } // Create rectangle that covers the enter area RectangleF gradientRect = new RectangleF(drawRect.X - 1, drawRect.Y - 1, drawRect.Width + 2, drawRect.Height + 2); // Cannot draw a zero length rectangle if ((gradientRect.Width > 0) && (gradientRect.Height > 0)) { // Draw entire area in a gradient color effect cache.entireBrush = new LinearGradientBrush(gradientRect, CommonHelper.WhitenColor(color1, 0.92f, 0.92f, 0.92f), color1, AngleFromOrientation(orientation)); cache.entireBrush.Blend = _rounded1Blend; } RectangleF ellipseRect; PointF ellipseCenter; int ellipseHeight = Math.Max(1, drawRect.Height / 4); int ellipseWidth = Math.Max(1, (tracking ? drawRect.Width : drawRect.Width / 4)); // Ellipse is based on the orientation switch (orientation) { default: case VisualOrientation.Top: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Bottom - ellipseHeight, drawRect.Width + ellipseWidth * 2, ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Bottom); break; case VisualOrientation.Bottom: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, drawRect.Width + ellipseWidth * 2, ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Top); break; case VisualOrientation.Left: ellipseRect = new RectangleF(drawRect.Right - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Right, ellipseRect.Top + (ellipseRect.Height / 2)); break; case VisualOrientation.Right: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left, ellipseRect.Top + (ellipseRect.Height / 2)); break; } cache.ellipsePath = new GraphicsPath(); cache.ellipsePath.AddEllipse(ellipseRect); cache.insideLighten = new PathGradientBrush(cache.ellipsePath); cache.insideLighten.CenterPoint = ellipseCenter; cache.insideLighten.CenterColor = color2; cache.insideLighten.Blend = _rounded2Blend; cache.insideLighten.SurroundColors = new Color[] { Color.Transparent }; } if (cache.entireBrush != null) { using(Clipping clip = new Clipping(g, cache.clipPath)) { g.FillRectangle(cache.entireBrush, cache.drawRect); g.FillPath(cache.insideLighten, cache.ellipsePath); } } } return memento; }
private static IDisposable DrawBackExpert(Rectangle drawRect, Color color1, Color color2, VisualOrientation orientation, Graphics g, IDisposable memento, bool total, bool tracking) { // Cannot draw a zero length rectangle if ((drawRect.Width > 0) && (drawRect.Height > 0)) { bool generate = true; MementoBackExpertChecked cache; // Access a cache instance and decide if cache resources need generating if ((memento == null) || !(memento is MementoBackExpertChecked)) { if (memento != null) { memento.Dispose(); } cache = new MementoBackExpertChecked(drawRect, color1, color2, orientation); memento = cache; } else { cache = (MementoBackExpertChecked)memento; generate = !cache.UseCachedValues(drawRect, color1, color2, orientation); } // Do we need to generate the contents of the cache? if (generate) { // Dispose of existing values cache.Dispose(); // If not drawing total area... if (!total) { // Update to draw the inside area instead // Жестко прописанное уменьшение внутренней части фона, не поддающееся регулированию при помощи палитры drawRect.Inflate(-1, -1); cache.drawRect = drawRect; cache.clipPath = new GraphicsPath(); cache.clipPath.AddLine(drawRect.X + 1, drawRect.Y, drawRect.Right - 1, drawRect.Y); cache.clipPath.AddLine(drawRect.Right - 1, drawRect.Y, drawRect.Right, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Right, drawRect.Y + 1, drawRect.Right, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Right, drawRect.Bottom - 2, drawRect.Right - 2, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Right - 2, drawRect.Bottom, drawRect.Left + 1, drawRect.Bottom); cache.clipPath.AddLine(drawRect.Left + 1, drawRect.Bottom, drawRect.Left, drawRect.Bottom - 2); cache.clipPath.AddLine(drawRect.Left, drawRect.Bottom - 2, drawRect.Left, drawRect.Y + 1); cache.clipPath.AddLine(drawRect.Left, drawRect.Y + 1, drawRect.X + 1, drawRect.Y); } else { cache.clipPath = new GraphicsPath(); cache.clipPath.AddRectangle(drawRect); } // Create rectangle that covers the enter area RectangleF gradientRect = new RectangleF(drawRect.X - 1, drawRect.Y - 1, drawRect.Width + 2, drawRect.Height + 2); // Cannot draw a zero length rectangle if ((gradientRect.Width > 0) && (gradientRect.Height > 0)) { // Draw entire area in a gradient color effect // А также жествое изменение цвета cache.entireBrush = new LinearGradientBrush(gradientRect, CommonHelper.WhitenColor(color1, 0.92f, 0.92f, 0.92f), color1, AngleFromOrientation(orientation)); cache.entireBrush.Blend = _rounded1Blend; } RectangleF ellipseRect; PointF ellipseCenter; int ellipseHeight = Math.Max(1, drawRect.Height / 4); int ellipseWidth = Math.Max(1, (tracking ? drawRect.Width : drawRect.Width / 4)); // Ellipse is based on the orientation switch (orientation) { default: case VisualOrientation.Top: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Bottom - ellipseHeight, drawRect.Width + ellipseWidth * 2, ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Bottom); break; case VisualOrientation.Bottom: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, drawRect.Width + ellipseWidth * 2, ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left + (ellipseRect.Width / 2), ellipseRect.Top); break; case VisualOrientation.Left: ellipseRect = new RectangleF(drawRect.Right - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Right, ellipseRect.Top + (ellipseRect.Height / 2)); break; case VisualOrientation.Right: ellipseRect = new RectangleF(drawRect.Left - ellipseWidth, drawRect.Top - ellipseHeight, ellipseWidth * 2, drawRect.Height + ellipseHeight * 2); ellipseCenter = new PointF(ellipseRect.Left, ellipseRect.Top + (ellipseRect.Height / 2)); break; } cache.ellipsePath = new GraphicsPath(); cache.ellipsePath.AddEllipse(ellipseRect); cache.insideLighten = new PathGradientBrush(cache.ellipsePath); cache.insideLighten.CenterPoint = ellipseCenter; cache.insideLighten.CenterColor = color2; cache.insideLighten.Blend = _rounded2Blend; cache.insideLighten.SurroundColors = new Color[] { Color.Transparent }; } if (cache.entireBrush != null) { using (Clipping clip = new Clipping(g, cache.clipPath)) { g.FillRectangle(cache.entireBrush, cache.drawRect); g.FillPath(cache.insideLighten, cache.ellipsePath); } } } return(memento); }