public static FeatheredRectangle Union(FeatheredRectangle a, FeatheredRectangle b) { Rectangle rslt = Rectangle.Union(a._rect, b._rect); FeatheredRectangle retVal = new FeatheredRectangle(rslt.Location, rslt.Size, System.Math.Max(a._feather, b._feather)); retVal.BorderOffset = System.Math.Max(a._border, b._border); return(retVal); }
public static FeatheredRectangle Intersect(FeatheredRectangle a, FeatheredRectangle b) { Rectangle rslt = Rectangle.Intersect(a._rect, b._rect); if (!rslt.IsEmpty) { FeatheredRectangle retVal = new FeatheredRectangle(rslt.Location, rslt.Size, System.Math.Max(a._feather, b._feather)); retVal.BorderOffset = System.Math.Max(a._border, b._border); return(retVal); } else { return(FeatheredRectangle.Empty); } }
protected override void OnPaint(PaintEventArgs pevent) { Graphics g = pevent.Graphics; g.Clear(this.Parent.BackColor); int iFeatherSq = this._fthr * 2; int iBorderHalf = this._brdWidth / 2; PointF pCenter = new PointF(this.ClientRectangle.Right - (this.ClientRectangle.Width / 2), this.ClientRectangle.Bottom - (this.ClientRectangle.Height / 2)); // Set the button rotation transform. using (Matrix gMat = new Matrix()) { #region Set the Blending Mode //----------------------------------------------------------------------- if (this._mSamp) { g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.Bicubic; } //----------------------------------------------------------------------- #endregion #region Set the clipping bounds for drawing //----------------------------------------------------------------------- if (this._fthr > 0 || this._btnShape != null) { if (this._btnShape == null) SetButtonRegion(); g.SetClip(this._btnShape, CombineMode.Replace); } //----------------------------------------------------------------------- #endregion #region Draw the background based on button style/mouse status //----------------------------------------------------------------------- // Determine the background rectangle. RectangleF rBndsF = (this._btnShape != null) ? this._btnShape.GetBounds() : new RectangleF( new PointF((float)this.ClientRectangle.Left, (float)this.ClientRectangle.Top), new SizeF((float)this.ClientRectangle.Width, (float)this.ClientRectangle.Height)); // We need to clear the button with the background color before we go any further. g.Clear((this.Enabled) ? ((this.ToggleType && this.Activated && this.ToggleActiveColor != Color.Empty) ? this.ToggleActiveColor : this.BackColor) : this._disBcolor); Image bgImg = null; if (this.Enabled) { // Determine the appropriate background image if (this._btnType == AdvButtonStyle.Image && this._imgDown != null && (this._msDown || (this._toggleType && this._trigd))) bgImg = (this._imgDown.Clone() as Image); else if (this._btnType == AdvButtonStyle.Image && this._imgHover != null && this._msOver) bgImg = (this._imgHover.Clone() as Image); else if (this.BackgroundImage != null) bgImg = (this.BackgroundImage.Clone() as Image); if (bgImg != null) { gMat.RotateAt(this._rotBgImgDeg, pCenter); g.Transform = gMat; // We need to draw the image before drawing the gradient. switch (this.BackgroundImageLayout) { case ImageLayout.Center: g.DrawImageUnscaled(bgImg, (int)((rBndsF.Width / 2) - (bgImg.Width / 2)), (int)((rBndsF.Height / 2) - (bgImg.Height / 2))); break; case ImageLayout.None: g.DrawImageUnscaled(bgImg, (int)rBndsF.X, (int)rBndsF.Y); break; case ImageLayout.Stretch: g.DrawImage(bgImg, rBndsF); break; case ImageLayout.Tile: using (TextureBrush iBrush = new TextureBrush(bgImg, WrapMode.Tile, new Rectangle(0, 0, bgImg.Width, bgImg.Height))) g.FillRectangle(iBrush, rBndsF); break; case ImageLayout.Zoom: float iW = 0, iH = 0; if (bgImg.Width > rBndsF.Width && bgImg.Height > rBndsF.Height) { // The picture is larger than the bounding rectangle // in both width and height, so we have to determine // how to shrink it. } else if (bgImg.Width > rBndsF.Width) { // The height is fine, but it's too wide. iW = rBndsF.Width; iH = (rBndsF.Width * bgImg.Height) / bgImg.Width; } else if (bgImg.Height > rBndsF.Height) { // The width is fine, but it's too tall. iW = (rBndsF.Height * bgImg.Width) / bgImg.Height; } else { // If we get here, it means the image is smaller than // the bound rectangle, so we get to enlarge it. // First, we have to figure out whether width or // height gets precidence over the final size. } break; } gMat.Reset(); g.Transform = gMat; } // Fill the background based on the button style. switch (this._btnType) { case AdvButtonStyle.Flat: // Fill the new button drawing region with the specified backcolor. if ((this._msDown || (this._toggleType && this._trigd)) && bgImg == null) g.Clear((this.FlatAppearance.MouseDownBackColor != Color.Empty) ? this.FlatAppearance.MouseDownBackColor : this.BackColor); else if (this._msOver && bgImg == null) g.Clear((this.FlatAppearance.MouseOverBackColor != Color.Empty) ? this.FlatAppearance.MouseOverBackColor : this.BackColor); //else if (bgImg == null) // g.Clear(this.BackColor); break; case AdvButtonStyle.Popup: //if (bgImg == null) // g.Clear(this.BackColor); if (bgImg == null && (this._toggleType && this._trigd)) g.Clear(ControlPaint.Light(this.BackColor)); break; case AdvButtonStyle.Standard: //if (bgImg == null) // g.Clear(this.BackColor); Color hColor = Color.Empty, sColor = Color.Empty, bColor = Color.Empty; // Get the base background color Color baseClr = this.BackColor; // If this is s "Toggle" button and a different BG color is specified and the button // is currently triggered, then set the background color to the ActiveToggleColor. if (this._toggleType && this._tglClr != Color.Empty && this._trigd) baseClr = this._tglClr; // If the background image is null, we're drawing the background in color. // Otherwise, we use black and white to overlay on top of the image. if (bgImg == null) { hColor = Color.FromArgb(System.Math.Min(baseClr.R + (int)((float)this._3dHeight * this._hlMul), 255), System.Math.Min(baseClr.G + (int)((float)this._3dHeight * this._hlMul), 255), System.Math.Min(baseClr.B + (int)((float)this._3dHeight * this._hlMul), 255)); sColor = Color.FromArgb(System.Math.Max(baseClr.R - this._3dHeight, 0), System.Math.Max(baseClr.G - this._3dHeight, 0), System.Math.Max(baseClr.B - this._3dHeight, 0)); bColor = this.BackColor; } else { hColor = Color.FromArgb(this._3dHeight, Color.White); sColor = Color.FromArgb(this._3dHeight, Color.Black); bColor = Color.Transparent; } ColorBlend blend = new ColorBlend(4); if (this._msDown || (this._toggleType && this._trigd)) blend.Colors = new Color[] { sColor, sColor, bColor, hColor }; else blend.Colors = new Color[] { hColor, hColor, bColor, sColor }; blend.Positions = new float[] { 0.0f, ((this._hlMul / 2) / 10), 0.5f, 1.0f }; // File the rectangle with the gradient. if (rBndsF.Width > 0 && rBndsF.Height > 0) using (LinearGradientBrush backBrush = new LinearGradientBrush(rBndsF, bColor, bColor, LinearGradientMode.Vertical)) { backBrush.InterpolationColors = blend; g.FillRectangle(backBrush, rBndsF); } break; case AdvButtonStyle.Beveled: //if (bgImg == null) // g.Clear(this.BackColor); break; case AdvButtonStyle.Image: if ((this._msDown || (this._toggleType && this._trigd)) && bgImg == null) g.Clear((this.FlatAppearance.MouseDownBackColor != Color.Empty) ? this.FlatAppearance.MouseDownBackColor : this.BackColor); else if (this._msOver && bgImg == null) g.Clear((this.FlatAppearance.MouseOverBackColor != Color.Empty) ? this.FlatAppearance.MouseOverBackColor : this.BackColor); break; } } if (bgImg != null) bgImg.Dispose(); //----------------------------------------------------------------------- #endregion #region Draw the text/image on the button. //----------------------------------------------------------------------- if (this._btnType != AdvButtonStyle.Image) { #region Draw Text-Based Button if (this._msOver && !this._msDown && this._btnType == AdvButtonStyle.Popup) gMat.Translate(-1.0f, -0.5f); else if ((this._msDown || (this._toggleType && this._trigd)) && (this._btnType == AdvButtonStyle.Popup || this._btnType == AdvButtonStyle.Beveled)) gMat.Translate(1.0f, 0.5f); gMat.RotateAt(this._rotTxtDeg, pCenter); g.Transform = gMat; using (SolidBrush tBrush = new SolidBrush((this.Enabled) ? this.ForeColor : this._disFcolor)) using (StringFormat format = new StringFormat()) { format.Trimming = ((this.AutoEllipsis) ? StringTrimming.EllipsisCharacter : StringTrimming.Character); if (this.RightToLeft == RightToLeft.Yes) format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; if (!this._txtWrp) format.FormatFlags |= StringFormatFlags.NoWrap; if (this._txtVert) format.FormatFlags |= StringFormatFlags.DirectionVertical; #region Set the string alignment based on the TextAlign property. //--------------------------------------------------------------- switch (this.TextAlign) { case ContentAlignment.BottomCenter: format.LineAlignment = StringAlignment.Far; format.Alignment = StringAlignment.Center; break; case ContentAlignment.BottomLeft: format.LineAlignment = StringAlignment.Far; format.Alignment = StringAlignment.Near; break; case ContentAlignment.BottomRight: format.LineAlignment = StringAlignment.Far; format.Alignment = StringAlignment.Far; break; case ContentAlignment.MiddleCenter: format.LineAlignment = StringAlignment.Center; format.Alignment = StringAlignment.Center; break; case ContentAlignment.MiddleLeft: format.LineAlignment = StringAlignment.Center; format.Alignment = StringAlignment.Near; break; case ContentAlignment.MiddleRight: format.LineAlignment = StringAlignment.Center; format.Alignment = StringAlignment.Far; break; case ContentAlignment.TopCenter: format.LineAlignment = StringAlignment.Near; format.Alignment = StringAlignment.Center; break; case ContentAlignment.TopLeft: format.LineAlignment = StringAlignment.Near; format.Alignment = StringAlignment.Near; break; case ContentAlignment.TopRight: format.LineAlignment = StringAlignment.Near; format.Alignment = StringAlignment.Far; break; } //--------------------------------------------------------------- #endregion // Calculate the viable text region. // This will be altered to adjust for a forground image, // if one has been specified. RectangleF txtBnds = RectangleF.Empty; float rX = (this._fthr / 2) + iBorderHalf; float rY = (this._fthr / 2) + iBorderHalf; float rW = this.ClientRectangle.Width - (rX * 2) - this._fgReserved; float rH = this.ClientRectangle.Height - (rY * 2); #region Offset text and draw image, if provided //--------------------------------------------------------------- if (this.Image != null) { //ImageAttributes imgAttr = new ImageAttributes(); // Copy the correct Image object into the curImg variable. // This way we have a singular object to reference in the // following code. Bitmap curImg; if (this._imgDown != null && (this._msDown || (this._toggleType && this._trigd))) curImg = (this._imgDown as Bitmap); else if (this._imgHover != null && this._msOver) curImg = (this._imgHover as Bitmap); else curImg = (this.Image as Bitmap); if (curImg != null) { if (!this.Enabled) { try { curImg = BitmapFilter.GrayScale(curImg); curImg.MakeTransparent(); } catch { } } float iPicX = 0, iPicY = 0; if (!string.IsNullOrEmpty(this.Text)) { // Calcuate the image offset for the current button state. SizeF txtSize = g.MeasureString(this.Text, this.Font, new SizeF(rW, rH), format); switch (this.TextImageRelation) { case TextImageRelation.ImageAboveText: #region Draw image above text position //----------------------------------------------- // Vertical Allignment if (this.TextAlign == ContentAlignment.BottomCenter || this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.BottomRight) { // Bottom iPicY = (rH - (curImg.Height + txtSize.Height + this._imgPad)) + rY; } else if (this.TextAlign == ContentAlignment.TopCenter || this.TextAlign == ContentAlignment.TopLeft || this.TextAlign == ContentAlignment.TopRight) { // Top iPicY = rY + this._imgPad; rY += curImg.Height + (this._imgPad * 2); } else { // Middle iPicY = ((rH / 2) - ((curImg.Height + this._imgPad + txtSize.Height) / 2)) + rY; rY += (curImg.Height + this._imgPad) / 2; } // Horizontal Allignment if (this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.MiddleLeft || this.TextAlign == ContentAlignment.TopLeft) { // Left iPicX = rX + ((txtSize.Width / 2) - (curImg.Width / 2)); } else if (this.TextAlign == ContentAlignment.BottomRight || this.TextAlign == ContentAlignment.MiddleRight || this.TextAlign == ContentAlignment.TopRight) { // Right iPicX = ((rW - txtSize.Width) + ((txtSize.Width / 2) - (curImg.Width / 2))) + rX; } else { // Center iPicX = ((rW / 2) - (curImg.Width / 2)) + rX; } break; //----------------------------------------------- #endregion case TextImageRelation.ImageBeforeText: #region Draw image to the left of the text //----------------------------------------------- // Vertical Allignment if (this.TextAlign == ContentAlignment.BottomCenter || this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.BottomRight) { // Bottom iPicY = (rH - curImg.Height) + rY; rH -= System.Math.Max((curImg.Height - txtSize.Height), (txtSize.Height - curImg.Height)) / 2; } else if (this.TextAlign == ContentAlignment.TopCenter || this.TextAlign == ContentAlignment.TopLeft || this.TextAlign == ContentAlignment.TopRight) { // Top iPicY = rY + this._imgPad; rY += System.Math.Max((curImg.Height - txtSize.Height), (txtSize.Height - curImg.Height)) / 2; } else { // Middle iPicY = ((rH / 2) - (curImg.Height / 2)) + rY; } // Horizontal Allignment if (this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.MiddleLeft || this.TextAlign == ContentAlignment.TopLeft) { // Left iPicX = rX + this._imgPad; rX += curImg.Width + (this._imgPad * 2); } else if (this.TextAlign == ContentAlignment.BottomRight || this.TextAlign == ContentAlignment.MiddleRight || this.TextAlign == ContentAlignment.TopRight) { // Rigtht iPicX = (rW - (txtSize.Width + curImg.Width + this._imgPad)) + rX; } else { // Center iPicX = ((rW / 2) - ((curImg.Width + txtSize.Width + _imgPad) / 2)) + rX; rX += (curImg.Width + this._imgPad) / 2; } break; //----------------------------------------------- #endregion case TextImageRelation.Overlay: #region Draw image in the same position as the text //----------------------------------------------- // Vertical Allignment if (this.TextAlign == ContentAlignment.BottomCenter || this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.BottomRight) { // Bottom iPicY = (rH - rY) - (curImg.Height); } else if (this.TextAlign == ContentAlignment.TopCenter || this.TextAlign == ContentAlignment.TopLeft || this.TextAlign == ContentAlignment.TopRight) { // Top iPicY = rY; } else { // Middle iPicY = ((rH / 2) - (curImg.Height / 2)) + rY; } // Horizontal Allignment if (this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.MiddleLeft || this.TextAlign == ContentAlignment.TopLeft) { // Left iPicX = rX; } else if (this.TextAlign == ContentAlignment.BottomRight || this.TextAlign == ContentAlignment.MiddleRight || this.TextAlign == ContentAlignment.TopRight) { // Right iPicX = (rW - rX) - (curImg.Width); } else { // Center iPicX = ((rW / 2) - (curImg.Width / 2)) + rX; } break; //----------------------------------------------- #endregion case TextImageRelation.TextAboveImage: #region Draw image below text position //----------------------------------------------- // Vertical Allignment if (this.TextAlign == ContentAlignment.BottomCenter || this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.BottomRight) { // Bottom iPicY = (rH - curImg.Height) + rY; rH -= (curImg.Height + this._imgPad); } else if (this.TextAlign == ContentAlignment.TopCenter || this.TextAlign == ContentAlignment.TopLeft || this.TextAlign == ContentAlignment.TopRight) { // Top iPicY = (txtSize.Height + this._imgPad) + rY; } else { // Middle iPicY = (((rH / 2) - ((curImg.Height + this._imgPad + txtSize.Height) / 2)) + (txtSize.Height + this._imgPad)) + rY; rH -= (curImg.Height + this._imgPad); } // Horizontal Allignment if (this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.MiddleLeft || this.TextAlign == ContentAlignment.TopLeft) { // Left iPicX = rX + ((txtSize.Width / 2) - (curImg.Width / 2)); } else if (this.TextAlign == ContentAlignment.BottomRight || this.TextAlign == ContentAlignment.MiddleRight || this.TextAlign == ContentAlignment.TopRight) { // Right iPicX = ((rW - txtSize.Width) + ((txtSize.Width / 2) - (curImg.Width / 2))) + rX; } else { // Center iPicX = ((rW / 2) - (curImg.Width / 2)) + rX; } break; //----------------------------------------------- #endregion case TextImageRelation.TextBeforeImage: #region Draw image to the right of the text //----------------------------------------------- // Vertical Allignment if (this.TextAlign == ContentAlignment.BottomCenter || this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.BottomRight) { // Bottom iPicY = (rH - curImg.Height) + rY; rH -= System.Math.Max((curImg.Height - txtSize.Height), (txtSize.Height - curImg.Height)) / 2; } else if (this.TextAlign == ContentAlignment.TopCenter || this.TextAlign == ContentAlignment.TopLeft || this.TextAlign == ContentAlignment.TopRight) { // Top iPicY = rY + this._imgPad; rY += System.Math.Max((curImg.Height - txtSize.Height), (txtSize.Height - curImg.Height)) / 2; } else { // Middle iPicY = ((rH / 2) - (curImg.Height / 2)) + rY; } // Horizontal Allignment if (this.TextAlign == ContentAlignment.BottomLeft || this.TextAlign == ContentAlignment.MiddleLeft || this.TextAlign == ContentAlignment.TopLeft) { // Left iPicX = rX + this._imgPad + txtSize.Width; } else if (this.TextAlign == ContentAlignment.BottomRight || this.TextAlign == ContentAlignment.MiddleRight || this.TextAlign == ContentAlignment.TopRight) { // Right iPicX = (rW - (curImg.Width + this._imgPad)) + rX; rW -= (curImg.Width + (this._imgPad * 2)); } else { // Center iPicX = ((rW / 2) + (((txtSize.Width / 2) + (curImg.Width / 2) + this._imgPad) / 2)) + rX; rW -= (curImg.Width + (this._imgPad * 2)); } break; //----------------------------------------------- #endregion } } else { GraphicsUnit pgUnit = g.PageUnit; RectangleF rect = curImg.GetBounds(ref pgUnit); iPicX = (rW / 2) - (float)(rect.Width / 2); iPicY = (rH / 2) - (float)(rect.Height / 2); } //g.DrawImage(curImg, new Rectangle((int)iPicX, (int)iPicY, curImg.Width, curImg.Height), 0, 0, curImg.Width, curImg.Height, GraphicsUnit.Pixel, imgAttr); g.DrawImageUnscaled(curImg, (int)iPicX, (int)iPicY); } curImg.Dispose(); } //--------------------------------------------------------------- #endregion txtBnds = new RectangleF(rX, rY, rW, rH); if (this.Enabled) { // Draw the text outline, if it's turned on. if (this._txtOutln && this._txtOutlnC != Color.Empty) using (GraphicsPath gpTextOutln = new GraphicsPath(FillMode.Alternate)) { gpTextOutln.AddString(this.Text, this.Font.FontFamily, (int)this.Font.Style, this.Font.Size * 1.318f, txtBnds, format); gpTextOutln.CloseAllFigures(); gpTextOutln.Flatten(); using (Pen tOutlnPen = new Pen(Color.FromArgb(this._txtOutlnO, this._txtOutlnC), this._txtOutlnW)) g.DrawPath(tOutlnPen, gpTextOutln); } // Draw the text shadow, if it's turned on. if (this._txtShd) using (GraphicsPath gpTextShadow = new GraphicsPath(FillMode.Winding)) { gpTextShadow.AddString(this.Text, this.Font.FontFamily, (int)this.Font.Style, this.Font.Size * 1.318f, txtBnds, format); gpTextShadow.CloseAllFigures(); gpTextShadow.Flatten(); using (Matrix matTrans = new Matrix()) { matTrans.Translate(this._txtShdW, this._txtShdW); gpTextShadow.Transform(matTrans); using (SolidBrush tShadowBrush = new SolidBrush(Color.FromArgb(this._txtShdO, Color.Black))) g.FillPath(tShadowBrush, gpTextShadow); } } } { //txtBnds.Offset(0.5f * (float)this._txtShdW, 1.0f * (float)this._txtShdW); //using (SolidBrush tsBrush = new SolidBrush(Color.FromArgb(this._txtShdO, Color.Black))) // g.DrawString(this.Text, this.Font, tsBrush, txtBnds, format); //txtBnds.Offset(0.5f * (float)this._txtShdW, 1.0f * (float)this._txtShdW); } // Finally, draw the actual text into the bounding rectangle. if (!string.IsNullOrEmpty(this.Text)) g.DrawString(this.Text, this.Font, tBrush, txtBnds, format); txtBnds = RectangleF.Empty; } gMat.Reset(); g.Transform = gMat; #endregion } else { #region Draw Image-Based Button // Determine which image we're going to draw based on the button state. Bitmap curImg = null; if (this._msDown || (this._toggleType && this._trigd)) { if (this._imgDown != null) curImg = (this._imgDown as Bitmap); else if (this._imgHover != null) curImg = (this._imgHover as Bitmap); else curImg = (this.Image as Bitmap); } else if (this._msOver && this._imgHover != null) curImg = (this._imgHover as Bitmap); else curImg = (this.Image as Bitmap); // Now draw the actuall image. if (curImg != null) { // If the button is disabled, we want to 'dim' the image. if (!this.Enabled) { curImg = BitmapFilter.GrayScale(curImg); curImg.MakeTransparent(); } ImageAttributes imgAttr = new ImageAttributes(); imgAttr.SetWrapMode(WrapMode.Clamp); g.DrawImage(curImg, new Rectangle(Imaging.CenterImage(curImg, Rectangle.Truncate(g.ClipBounds)), Size.Truncate(g.ClipBounds.Size)), 0, 0, curImg.Width, curImg.Height, GraphicsUnit.Pixel, imgAttr); } #endregion } //----------------------------------------------------------------------- #endregion #region Restore the clipping rectangle and draw the border. //----------------------------------------------------------------------- if (this.FlatStyle != AdvButtonStyle.Image) { float brdrWidth = (float)this._brdWidth; // If this button is the Form's default, we want to make the border "bold", // but before we restore the clipping region. #region Draw "Default" Button Border if (this.IsDefault && !(this._msOver || this._msDown)) { Color clrBldBorder = Color.FromArgb(160, this._brdClr); FeatheredRectangle rBldBorderPath = new FeatheredRectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2), this._fthr); using (Pen pBldBorder = new Pen(clrBldBorder, brdrWidth + 2)) { if (this._fthr > 0) { GraphicsPath grphPathBoldBorder = null; try { if (this._rndCrnr) { // Calculate the shape of the border FeatheredRectangle rBorderPath = new FeatheredRectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2), this._fthr); grphPathBoldBorder = rBorderPath.GetBorder(); } else { grphPathBoldBorder = this._btnShape; } // Draw the "Bold" border. g.DrawPath(pBldBorder, grphPathBoldBorder); } finally { if (grphPathBoldBorder != null) grphPathBoldBorder.Dispose(); } } else { Rectangle rBorder = new Rectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2)); g.DrawRectangle(pBldBorder, rBorder); rBorder = Rectangle.Empty; } } } #endregion g.SetClip(pevent.ClipRectangle, CombineMode.Replace); using (Pen pBorder = new Pen((this.Enabled) ? this._brdClr : this._disFcolor, brdrWidth)) { // We have to process the border differently it the button's // corners are feathered. if (this._fthr > 0) { GraphicsPath grphPath = null; try { if (this._rndCrnr) { // Calculate the shape of the border FeatheredRectangle rBorderPath = new FeatheredRectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2), this._fthr); grphPath = rBorderPath.GetBorder(); } else { grphPath = this._btnShape; } // Draw the hover/click border highlight if ((this._msOver || this._msDown) && this._hvrOpc > 0) using (GraphicsPath gpHighlight = (grphPath.Clone() as GraphicsPath)) { float offset = 3; Rectangle rBorder = Rectangle.Truncate(grphPath.GetBounds()); using (Matrix resizeMatrix = new Matrix()) { resizeMatrix.Scale((rBorder.Width - offset) / rBorder.Width, (rBorder.Height - offset) / rBorder.Height); resizeMatrix.Translate(((rBorder.Width - offset) / rBorder.Width) + (offset / 10), ((rBorder.Height - offset) / rBorder.Height) + (offset / 10)); gpHighlight.Transform(resizeMatrix); using (Pen overPen = new Pen(((this._msDown) ? Color.White : Color.FromArgb(this._hvrOpc, this._hvrClr)), ((this._msDown) ? 1.0f : 2.0f))) g.DrawPath(overPen, gpHighlight); } } // Finally, draw the actual border g.DrawPath(pBorder, grphPath); // For the 'popup' style, we need to make the button appear to 'popup' // if the mouse is hovering over it. // For the 'beveled' style, the highlight/shadow edges should always be visible. if ((this._btnType == AdvButtonStyle.Beveled && !this._msDown) || (this._btnType == AdvButtonStyle.Popup && this._msOver && !this._msDown)) { g.SetClip(this._btnShape, CombineMode.Replace); using (GraphicsPath gpBtnHlt = (grphPath.Clone() as GraphicsPath)) using (GraphicsPath gpBtnShw = (grphPath.Clone() as GraphicsPath)) { using (Matrix resizeMatrix = new Matrix()) { resizeMatrix.Translate(0.5f, 0.5f); gpBtnHlt.Transform(resizeMatrix); g.DrawPath(SystemPens.ButtonHighlight, gpBtnHlt); resizeMatrix.Reset(); resizeMatrix.Translate(-0.5f, -0.5f); gpBtnShw.Transform(resizeMatrix); g.DrawPath(SystemPens.ButtonShadow, gpBtnShw); } } } } finally { if (grphPath != null) grphPath.Dispose(); } } else { Rectangle rBorder = new Rectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2)); if (this._msOver || this._msDown) { Rectangle hoverEdge = new Rectangle(this._brdWidth, this._brdWidth, this.ClientRectangle.Width - (this._brdWidth * 3), this.ClientRectangle.Height - (this._brdWidth * 3)); using (Pen overPen = new Pen(((this._msDown) ? Color.White : Color.FromArgb(this._hvrOpc, this._hvrClr)), ((this._msDown) ? 1.0f : 2.0f))) g.DrawRectangle(overPen, hoverEdge); } g.DrawRectangle(pBorder, rBorder); rBorder = Rectangle.Empty; } } } //----------------------------------------------------------------------- #endregion } g = null; }
//*************************************************************************** // Private Methods // private void SetButtonRegion() { int iBorderHalf = this._brdWidth / 2; if (this._rndCrnr) { FeatheredRectangle fRegion = new FeatheredRectangle(iBorderHalf, iBorderHalf, this.ClientRectangle.Width - (iBorderHalf * 2), this.ClientRectangle.Height - (iBorderHalf * 2), this._fthr); this._btnShape = fRegion.GetRegion(); fRegion = FeatheredRectangle.Empty; } else { int t = iBorderHalf, l = iBorderHalf, b = this.ClientRectangle.Height - (iBorderHalf * 2), r = this.ClientRectangle.Width - (iBorderHalf * 2); Point[] pts = new Point[] { new Point(l, t + this._fthr), new Point(l + this._fthr, t), new Point(r - this._fthr, t), new Point(r, t + this._fthr), new Point(r, b - this._fthr), new Point(r - this._fthr, b), new Point(l + this._fthr, b), new Point(l, b - this._fthr) }; byte[] bts = new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.CloseSubpath }; this._btnShape = new GraphicsPath(pts, bts); } }
public static FeatheredRectangle Intersect(FeatheredRectangle a, FeatheredRectangle b) { Rectangle rslt = Rectangle.Intersect(a._rect, b._rect); if (!rslt.IsEmpty) { FeatheredRectangle retVal = new FeatheredRectangle(rslt.Location, rslt.Size, System.Math.Max(a._feather, b._feather)); retVal.BorderOffset = System.Math.Max(a._border, b._border); return retVal; } else return FeatheredRectangle.Empty; }
public static FeatheredRectangle Inflate(FeatheredRectangle rect, int x, int y) { return new FeatheredRectangle(rect.Location, new Size(rect.Width + x, rect.Height + y), rect.CornerFeather); }
public static FeatheredRectangle Union(FeatheredRectangle a, FeatheredRectangle b) { Rectangle rslt = Rectangle.Union(a._rect, b._rect); FeatheredRectangle retVal = new FeatheredRectangle(rslt.Location, rslt.Size, System.Math.Max(a._feather, b._feather)); retVal.BorderOffset = System.Math.Max(a._border, b._border); return retVal; }
//*************************************************************************** // Base-Class Override Methods // protected override void OnPaint(PaintEventArgs e) { { Graphics g = e.Graphics; Region origRegion = g.Clip.Clone(); g.Clear(this.BackColor); // We use this GraphicsPath to define the area the progress bar can // be drawn in. using (GraphicsPath progressArea = new GraphicsPath()) { // Prepare the clipping region for the progress bar area. FeatheredRectangle rClipRegion = new FeatheredRectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, this._fthr); // Set the clipping region for this graphics device to only allow // drawing in the correct area for the progress bar. g.ResetClip(); using (Region drawArea = new Region(rClipRegion.GetRegion())) g.SetClip(drawArea, CombineMode.Replace); // Fill the progress bar area with the selected backrgound color. g.Clear(this._bgColor); // Draw the background image, if any was specified. // We align the image to the control's ClientRectangle, but it // will be clipped to the feathered rectangle created in // the 'progressArea' GraphicsPath object. if (this._bgImg != null) { using (Image bgImg = (this._bgImg.Clone() as Image)) { bgImg.RotateFlip(this._bgImgRot); switch (this._bgImgLo) { case ImageLayout.Center: //int xPos = (this.ClientRectangle.Width / 2) - (this._bgImg.Width / 2); //int yPos = (this.ClientRectangle.Height / 2) - (this._bgImg.Height / 2); g.DrawImageUnscaled(bgImg, Imaging.CenterImage(bgImg, this.ClientRectangle)); break; case ImageLayout.None: g.DrawImageUnscaled(bgImg, this.ClientRectangle.Location); break; case ImageLayout.Stretch: g.DrawImage(bgImg, this.ClientRectangle); break; case ImageLayout.Tile: using (TextureBrush tBrush = new TextureBrush(bgImg, this._bgImgWm)) g.FillRectangle(tBrush, this.ClientRectangle); break; case ImageLayout.Zoom: g.DrawImage(bgImg, Imaging.ZoomImage(bgImg, this.ClientRectangle)); break; } } } // Calculate the drawing area for the progress bar. float thirdHt = (this.ClientRectangle.Height - this._border) / 3; int startLeft = this.ClientRectangle.Left + (this._border + 3); int startTop = this.ClientRectangle.Top + (this._border + 3); int valWidth = ((this.ClientRectangle.Width - ((this._border + 3) * 2)) * this._val) / (this._max + this._min); Rectangle bnds = new Rectangle(new Point(startLeft, startTop), new Size(valWidth, this.ClientRectangle.Height - ((this._border + 3) * 2))); // We're not going to draw the progress bar if the control is // not enabled. if (this.Enabled) { // If we determine that the drawing bounds is greater than nothing, // draw the progress bar. if (bnds.Width > 0 && bnds.Height > 0) { //// Reset the clipping region for the progress bars //FeatheredRectangle rProgressRegion = new FeatheredRectangle(bnds.Location.X, bnds.Location.Y, this.ClientRectangle.Width - ((this._border + 3) * 2), bnds.Height, this._fthr); //g.SetClip(rProgressRegion.GetRegion(), CombineMode.Replace); // Calculate the Highlight and Shadow colors // for the progress bar. Color hColor = RgbColor.LightenColor(this.ForeColor, 60); Color hhColor = RgbColor.LightenColor(this.ForeColor, 30); Color sColor = RgbColor.DarkenColor(this.ForeColor, 20); // Create the base brush. If the 3d effect is on, this will be // the top of the progress bar. Brush pBrush = null; if (this._3d) { pBrush = new LinearGradientBrush(new Rectangle(bnds.Location, bnds.Size), hhColor, hhColor, LinearGradientMode.Vertical); ColorBlend gradBlend = new ColorBlend(8); gradBlend.Colors = new Color[] { this.ForeColor, hColor, hColor, this.ForeColor, this.ForeColor, sColor, this.ForeColor, hhColor }; gradBlend.Positions = new float[] { 0.0f, 0.15f, 0.25f, 0.4f, 0.7f, 0.8f, 0.90f, 1.0f }; (pBrush as LinearGradientBrush).InterpolationColors = gradBlend; } else pBrush = new SolidBrush(this.ForeColor); // Finally, draw the progress bar according to the // specified ProgressBarStyle. switch (this.Style) { case ProgressBarStyle.Blocks: using (Matrix gMat = new Matrix()) { for (int i = 1; i < bnds.Width; i = i + this._blkWidth + this._blkSpace) { int blockWidth = (((this._val == this._max) && (i + this._blkWidth + this._blkSpace > bnds.Right)) ? System.Math.Min(bnds.Width - i, this._blkWidth) : this._blkWidth); Rectangle rBlock = new Rectangle(new Point((i) + bnds.Left, bnds.Top), new Size(blockWidth, bnds.Height)); gMat.RotateAt(this._rotBlockDeg, new PointF(rBlock.Right - (rBlock.Width / 2), rBlock.Bottom - (rBlock.Height / 2))); g.Transform = gMat; g.FillRectangle(pBrush, rBlock); if (this._pImg != null) { using (Image pImg = (this._pImg.Clone() as Image)) { pImg.RotateFlip(this._bgImgRot); switch (this._pImgLo) { case ImageLayout.Center: //int xPos = (rBlock.Width / 2) - (this._pImg.Width / 2); //int yPos = (rBlock.Height / 2) - (this._pImg.Height / 2); g.DrawImageUnscaled(pImg, Imaging.CenterImage(pImg, rBlock)); break; case ImageLayout.None: g.DrawImageUnscaled(pImg, rBlock.Location); break; case ImageLayout.Stretch: g.DrawImage(pImg, rBlock); break; case ImageLayout.Tile: using (TextureBrush tBrush = new TextureBrush(pImg, this._pImgWm)) g.FillRectangle(tBrush, rBlock); break; case ImageLayout.Zoom: g.DrawImage(pImg, Imaging.ZoomImage(pImg, rBlock)); break; } } } rBlock = Rectangle.Empty; gMat.Reset(); g.Transform = gMat; } } break; case ProgressBarStyle.Continuous: g.FillRectangle(pBrush, bnds); if (this._pImg != null) { using (Image pImg = (this._pImg.Clone() as Image)) { pImg.RotateFlip(this._pImgRot); switch (this._pImgLo) { case ImageLayout.Center: //int xPos = (bnds.Width / 2) - (this._pImg.Width / 2); //int yPos = (bnds.Height / 2) - (this._pImg.Height / 2); g.DrawImageUnscaled(pImg, Imaging.CenterImage(pImg, bnds)); break; case ImageLayout.None: //g.DrawImageUnscaled(pImg, bnds.Location); // If there's no scaling going on, then the image should be // drawn where the progress bar is. g.DrawImageUnscaled(pImg, new Point(bnds.Left + valWidth, bnds.Top + (bnds.Height / 2 - pImg.Height / 2))); break; case ImageLayout.Stretch: g.DrawImage(pImg, bnds); break; case ImageLayout.Tile: using (TextureBrush tBrush = new TextureBrush(pImg, this._pImgWm)) g.FillRectangle(tBrush, bnds); break; case ImageLayout.Zoom: g.DrawImage(pImg, Imaging.ZoomImage(pImg, bnds)); break; } } } break; case ProgressBarStyle.Marquee: break; } sColor = Color.Empty; hColor = Color.Empty; pBrush.Dispose(); } } // Draw any text on the progress bar. if (!string.IsNullOrEmpty(this.Text)) { using (StringFormat format = new StringFormat()) { // Vertical alignment. if (this._txtAlign == ContentAlignment.BottomCenter || this._txtAlign == ContentAlignment.BottomLeft || this._txtAlign == ContentAlignment.BottomRight) format.LineAlignment = StringAlignment.Far; else if (this._txtAlign == ContentAlignment.TopCenter || this._txtAlign == ContentAlignment.TopLeft || this._txtAlign == ContentAlignment.TopRight) format.LineAlignment = StringAlignment.Near; else format.LineAlignment = StringAlignment.Center; // Horizontal alignment. if (this._txtAlign == ContentAlignment.BottomLeft || this._txtAlign == ContentAlignment.MiddleLeft || this._txtAlign == ContentAlignment.TopLeft) format.LineAlignment = StringAlignment.Near; else if (this._txtAlign == ContentAlignment.BottomRight || this._txtAlign == ContentAlignment.MiddleRight || this._txtAlign == ContentAlignment.TopRight) format.LineAlignment = StringAlignment.Far; else format.LineAlignment = StringAlignment.Center; // Draw the text align either to the entire control, or // only the progress bar. string txtVal = this.Text.Replace(@"\v", this.Value.ToString()).Replace(@"\m", this._max.ToString()).Replace(@"\p", Convert.ToString(System.Math.Round((double)(this._val * 100) / this._max))); using (SolidBrush brush = new SolidBrush(this._txtColor)) if (this._txtAlignCtrl) g.DrawString(txtVal, this.Font, brush, new RectangleF(startLeft, startTop, this.ClientRectangle.Width - ((this._border + 3) * 2), this.ClientRectangle.Height - ((this._border + 3) * 2)), format); else if (g.MeasureString(txtVal, this.Font).Width > bnds.Width) g.DrawString(txtVal, this.Font, brush, (float)bnds.X, ((bnds.Height / 2) - (g.MeasureString(txtVal, this.Font).Height / 2)) + bnds.Y); else g.DrawString(txtVal, this.Font, brush, RectangleF.FromLTRB(bnds.Left, bnds.Top, bnds.Right, bnds.Bottom), format); } } if (this._mSamp) { g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; } // Draw the borders. using (Pen borderPen = new Pen(this.BorderColor, (float)this._border)) { if (this._3d) // Draw the top-left edge's inner drop shadow. using (GraphicsPath shadowPath = (rClipRegion.GetBorder().Clone() as GraphicsPath)) { shadowPath.Transform(new Matrix(rClipRegion.GetBounds(), new PointF[] { new PointF(1, 1), new PointF(rClipRegion.GetBounds().Width + 1, 1), new PointF(1, rClipRegion.GetBounds().Height + 1) })); using (Pen sPen = new Pen(Color.FromArgb(120, Color.Black), 1.5f)) g.DrawPath(sPen, shadowPath); shadowPath.Transform(new Matrix(rClipRegion.GetBounds(), new PointF[] { new PointF(1, 1), new PointF(rClipRegion.GetBounds().Width + 1, 1), new PointF(1, rClipRegion.GetBounds().Height + 1) })); using (Pen sPen = new Pen(Color.FromArgb(40, Color.Black), 2.0f)) g.DrawPath(sPen, shadowPath); } // Reset the clipping region before drawing the outter // border lines. g.ResetClip(); g.SetClip(origRegion, CombineMode.Replace); // Draw the border lines. g.DrawPath(borderPen, rClipRegion.GetBorder()); //} } bnds = Rectangle.Empty; } } }
public static FeatheredRectangle Inflate(FeatheredRectangle rect, int x, int y) { return(new FeatheredRectangle(rect.Location, new Size(rect.Width + x, rect.Height + y), rect.CornerFeather)); }
public static FeatheredRectangle FromLTRB(int left, int top, int right, int bottom) { return(FeatheredRectangle.FromLTRB(left, top, right, bottom, 0)); }