ToolStripDropDown transparent background and smooth Region - c#

I'm trying to create a custom popup window in my winforms project, which looks like so:
The problem with this is that the edges are smooth...
I'm achieving this like so:
public partial class BubblePopup : ToolStripDropDown
{
private const int BORDERWIDTH = 6;
private SolidBrush _backgroundBrush;
private int _borderRadius = 20;
public BubblePopup()
{
this.BackColor = Color.Transparent;
InitializeComponent();
//Method 1
Region = new Region(ControlUtilities.CreateBubblePath(new Rectangle(BORDERWIDTH - 1, BORDERWIDTH - 1, ClientSize.Width - (BORDERWIDTH * 2), ClientSize.Height - (BORDERWIDTH * 2)), _borderRadius));
/////////////
_backgroundBrush = new SolidBrush(Color.Blue);
}
//Method 1
protected override void OnSizeChanged(EventArgs e)
{
Region = new Region(ControlUtilities.CreateBubblePath(new Rectangle(BORDERWIDTH - 1, BORDERWIDTH - 1, ClientSize.Width - (BORDERWIDTH * 2), ClientSize.Height - (BORDERWIDTH * 2)), _borderRadius));
base.OnSizeChanged(e);
}
////////
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | 0x20;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
}
}
If I don't use the code enclosed by Method1 comments and I'm setting the background to transparent and setting the CreateParams flag to support transparency im getting the following result(I also tried overriding the OnPaintBackground event as well not to call the base.OnPaintBackground I got a black background then):
So I would either need a popup with my custom path with smooth region, or a transparent background would also work for me.
Also here's the code how I'm showing the popup:
private GeneralPopup _popupItem = new GeneralPopup();
private ToolStripControlHost _popupControlHost;
private BubblePopup _popup;
public Form1()
{
InitializeComponent();
_popupControlHost = new ToolStripControlHost(_popupItem);
_popupControlHost.Padding = new Padding(0);
_popupControlHost.Margin = new Padding(0);
_popupControlHost.AutoSize = false;
_popupControlHost.BackColor = Color.Transparent;
_popup = new BubblePopup();
_popup.Padding = new Padding(0);
_popup.Margin = new Padding(0);
_popup.AutoSize = true;
_popup.DropShadowEnabled = false;
_popup.Items.Add(_popupControlHost);
}
private void button1_Click(object sender, EventArgs e)
{
_popup.Show(button1,10,10);
}
Thanks in advance

Related

Translucent circular Control with text

I am working on a project wherein I need to add a Control with the shape of a Circle with some text in the middle.
My problem is the circle is too small, when I resize it, it overlaps other controls. I want to draw the circle same width as the square.
Otherwise. how can I make the Control's background transparent?
I am using the code below:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
{
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
}
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
}
}
}
This is a Custom Control derived from Control, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity: The level of opacity of the control BackGround [0, 255]
InnerPadding: The distance between the inner rectangle, which defines the circle bounds and the control bounds.
FontPadding: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behavior, adding these ControlStyles:
▶ ControlStyles.Opaque: prevents the painting of a Control's BackGround, so it's not managed by the System. Combined with CreateParams to set the Control's Extended Style to WS_EX_TRANSPARENT, the Control becomes completely transparent.
▶ ControlStyles.SupportsTransparentBackColor the control accepts Alpha values for it's BackGround color. Without also setting ControlStyles.UserPaint it won't be used to simulate transparency. We're doing that ourselves with other means.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox. Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Note and disclaimer:
This is a prototype Control, the custom Designer is missing (cannot post that here, too much code, also connected to a framework).
As presented here, it can be used to completely overlap other Controls in a Form or other containers. Partial overlapping is not handled in this simplified implementation.
The Font is hard-coded to Segoe UI, since this Font has a base-line that simplifies the position of the text in the middle of the circular area.
Other Fonts have a different base-line, which requires more complex handling.
See: TextBox with dotted lines for typing for the base math.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
[DesignerCategory("Code")]
public class RoundCenterLabel : Label, INotifyPropertyChanged, ISupportInitialize
{
private const int WS_EX_TRANSPARENT = 0x00000020;
private bool IsInitializing = false;
private Point MouseDownLocation = Point.Empty;
private readonly int fontPadding = 4;
private Font m_CustomFont = null;
private Color m_BackGroundColor;
private int m_InnerPadding = 0;
private int m_FontPadding = 25;
private int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
{
SetStyle(ControlStyles.Opaque |
ControlStyles.SupportsTransparentBackColor |
ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
m_CustomFont = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
BackColor = Color.LimeGreen;
ForeColor = Color.White;
}
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= WS_EX_TRANSPARENT;
return cp;
}
}
public new Font Font
{
get => m_CustomFont;
set {
m_CustomFont = value;
if (IsInitializing) return;
FontAdapter(value, DeviceDpi);
NotifyPropertyChanged();
}
}
public override string Text {
get => base.Text;
set { base.Text = value;
NotifyPropertyChanged();
}
}
public int InnerPadding {
get => m_InnerPadding;
set {
if (IsInitializing) return;
m_InnerPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged(); }
}
public int FontPadding {
get => m_FontPadding;
set {
if (IsInitializing) return;
m_FontPadding = ValidateRange(value, 0, ClientRectangle.Height - 10);
NotifyPropertyChanged();
}
}
public int Opacity {
get => m_Opacity;
set { m_Opacity = ValidateRange(value, 0, 255);
UpdateBackColor(m_BackGroundColor);
NotifyPropertyChanged();
}
}
public override Color BackColor {
get => m_BackGroundColor;
set { UpdateBackColor(value);
NotifyPropertyChanged();
}
}
protected override void OnLayout(LayoutEventArgs e)
{
base.OnLayout(e);
base.AutoSize = false;
}
private void NotifyPropertyChanged([CallerMemberName] string PropertyName = null)
{
InvalidateParent();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
MouseDownLocation = e.Location;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (e.Button == MouseButtons.Left) {
var loc = new Point(Left + (e.X - MouseDownLocation.X), Top + (e.Y - MouseDownLocation.Y));
InvalidateParent();
BeginInvoke(new Action(() => Location = loc));
}
}
private void InvalidateParent()
{
Parent?.Invalidate(Bounds, true);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
using (var format = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoWrap, CultureInfo.CurrentUICulture.LCID))
{
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (var circleBrush = new SolidBrush(m_BackGroundColor))
using (var foreBrush = new SolidBrush(ForeColor))
{
FontAdapter(m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(circleBrush, rect);
e.Graphics.DrawString(Text, m_CustomFont, foreBrush, rect, format);
};
};
}
public void BeginInit() => IsInitializing = true;
public void EndInit()
{
IsInitializing = false;
Font = new Font("Segoe UI", 50, FontStyle.Regular, GraphicsUnit.Pixel);
FontPadding = m_FontPadding;
InnerPadding = m_InnerPadding;
}
private RectangleF InnerRectangle()
{
(float Min, _) = GetMinMax(ClientRectangle.Height, ClientRectangle.Width);
var size = new SizeF(Min - (m_InnerPadding / 2), Min - (m_InnerPadding / 2));
var position = new PointF((ClientRectangle.Width - size.Width) / 2,
(ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
}
private void FontAdapter(Font font, float dpi)
{
RectangleF rect = InnerRectangle();
float fontSize = ValidateRange(
(int)(rect.Height - m_FontPadding), 6,
(int)(rect.Height - m_FontPadding)) / (dpi / 72.0F) - fontPadding;
m_CustomFont.Dispose();
m_CustomFont = new Font(font.FontFamily, fontSize, font.Style, GraphicsUnit.Pixel);
}
private void UpdateBackColor(Color color)
{
m_BackGroundColor = Color.FromArgb(m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = m_BackGroundColor;
}
private int ValidateRange(int Value, int Min, int Max)
=> Math.Max(Math.Min(Value, Max), Min); // (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private (float, float) GetMinMax(float Value1, float Value2)
=> (Math.Min(Value1, Value2), Math.Max(Value1, Value2));
}

Can't get overridden OnPaint function to work for custom Panel - C#

I'm trying to create a border for my Panels that can change in thickness and color. After doing some research, I discovered that the only good way to do this is to create my own custom Panel and to override the OnPaint function. This is what I've got:
public class CustomPanel : Panel
{
public CustomPanel() : base()
{
SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (BorderStyle == BorderStyle.FixedSingle)
{
int thickness = 30;
int halfThickness = thickness / 2;
using (Pen p = new Pen(Color.Black, thickness))
{
e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
halfThickness,
ClientSize.Width - thickness, ClientSize.Height - thickness));
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
CustomPanel cp = new CustomPanel()
{
BackColor = SystemColors.ActiveCaption,
BorderStyle = BorderStyle.FixedSingle,
Margin = new Padding(0),
Size = new Size(45, 45)
};
cp.Paint += new PaintEventHandler(OnPaint);
}
Note: I'm not entirely sure what the part about SetStyle in the constructor is, but some people said that helped them. No luck for me.
Anyways, the last line of code gives me an error that says, "No overload for 'OnPaint' matches delegate 'PaintEventHandler'."
And before you say, "change OnPaint(PaintEventArgs e) to OnPaint(object sender, PaintEventArgs e)," if I do that I get the error message, "'CustomPanel.OnPaint(object, PaintEventArgs)': no suitable method found to override."
So I'm not really sure what to do.
Thanks for the help!

how to make a vertical progress bar

I'm trying to make a vertical progress bar and I understand that there isn't any easy way to do it.
I've seen this code floating around the forums:
public class VerticalProgressBar : ProgressBar
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= 0x04;
return cp;
}
}
}
My question is where do I put this code? Does it go in my program.cs file or the form that the progress bar is on?
It doesn't matter where you put the code, you only have to make sure you are creating a VerticalProgressBar in your Form.Designer.cs file.
You have to change
private System.Windows.Forms.ProgressBar progressBar1
to
private VerticalProgressBar progressBar1
(or whatever it is called) and
this.progressBar1 = new System.Windows.Forms.ProgressBar();
to
this.progressBar1 = new VerticalProgressBar();
Still don't have this control available in VS 2022 so I used a TablePanelLayout with one column and two rows. and just changed the RowStyle SizeType percent. You can easily add code to change the panel color when a limit is reached etc.
public class BarGraph : Panel
{
private Panel panel1;
private Panel panel2;
private TableLayoutPanel table;
private float percentValue;
public BarGraph()
{
table = new TableLayoutPanel();
table.ColumnCount = 1;
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
table.Name = "tableLayoutPanel1";
table.RowCount = 2;
table.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
table.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
table.Dock = DockStyle.Fill;
table.Margin = new Padding(0);
table.Padding = new Padding(0);
table.CellBorderStyle = TableLayoutPanelCellBorderStyle.None;
panel1 = new Panel();
panel2 = new Panel();
panel1.AutoSize = false;
panel1.Dock = DockStyle.Fill;
panel1.Padding = new Padding(0);
panel1.Margin = new Padding(0);
panel2.AutoSize = false;
panel2.Dock = DockStyle.Fill;
panel2.Padding = new Padding(0);
panel2.Margin = new Padding(0);
panel1.BackColor = System.Drawing.Color.White;
panel2.BackColor = System.Drawing.Color.Blue;
table.Controls.Add(panel1, 0, 0);
table.Controls.Add(panel2, 0, 1);
this.Controls.Add(table);
this.Size = new System.Drawing.Size(150, 500);
SetValue("50");
}
public float GetValue()
{
return this.percentValue;
}
public void IncreaseValue()
{
IncrementValue(percentValue - 1);
}
public void DecreaseValue()
{
IncrementValue(percentValue + 1);
}
private void IncrementValue(float value)
{
SetValue(value.ToString());
}
public void SetValue(string value)
{
float.TryParse(value, out percentValue);
if ((percentValue >= 0) && (percentValue <=100))
{
table.RowStyles.RemoveAt(1);
table.RowStyles.RemoveAt(0);
table.RowStyles.Add(new RowStyle(SizeType.Percent, 100 - percentValue));
table.RowStyles.Add(new RowStyle(SizeType.Percent, percentValue));
}
}
}
If this is a brand new application, use WPF. vertical progress bars are built-in
<ProgressBar Orientation="Vertical" />
I found this post while looking for a way to make a vertical progress bar and used code in the question as the answer to my own problem. The accepted is right for sure so ✔ and ✔.
I'm adding this as just a bit of added value hopefully. In my own project I also needed to customize the color. I ended up using the OP's question to make my class and modified it so that ForeColor can be set to change the indicator color. All this and a working sample to boot.
class VerticalProgressBar : ProgressBar
{
public VerticalProgressBar() => SetWindowTheme(Handle, string.Empty, string.Empty);
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= 0x04;
return cp;
}
}
[DllImport("uxtheme", ExactSpelling = true, CharSet = CharSet.Unicode)]
public extern static Int32 SetWindowTheme(IntPtr hWnd,
String textSubAppName, String textSubIdList);
}
Designer code
"Where to put the code" (as stated in the accepted answer).
private void InitializeComponent()
{
this.progressBarTemperature = new weather_client.VerticalProgressBar();
this.SuspendLayout();
.
.
.
//
// progressBarTemperature
//
this.progressBarTemperature.Location = new System.Drawing.Point(35, 12);
this.progressBarTemperature.Name = "progressBarTemperature";
this.progressBarTemperature.Size = new System.Drawing.Size(20, 113);
this.progressBarTemperature.TabIndex = 2;
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(385, 144);
this.Controls.Add(this.progressBarTemperature);
.
.
.
this.Name = "MainForm";
this.Text = "Main Form";
this.ResumeLayout(false);
}
private VerticalProgressBar progressBarTemperature;

Adding custom components programmatically at runtime

I'm having a problem using custom components at runtime.
I have this custom FlowLayoutPanel component:
public partial class UserControl1 : System.Windows.Forms.FlowLayoutPanel
{
[Browsable(false)]
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e){}
public UserControl1(){}
}
it has nothing complicated. All it does is making the background transparent.
I added this component to my Toolbox using it's dll and it works perfectly fine when I drag and drop it to my Form. The problem is, I can't add it programmatically at runtime.
When I run the code below it should draw the picture on top of my custom FlowLayoutControl.
But unfortunately it does nothing.
The custom component is under the WindowsFormsControlLibrary1 namespace.
namespace MyFilm_v2._0
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
UserControl1 test = new UserControl1();
test.BackColor = Color.Transparent;
test.Location = new Point(0, 110);
test.Width = 660;
test.Height = 478;
PictureBox b = new PictureBox();
b.Location = new Point(100, 100);
b.Width = 320;
b.Height = 475;
b.Image = Properties.Resources.movie;
this.Controls.Add(b);
//this.customScrollbar1.Minimum = 0;
//this.customScrollbar1.Maximum = test.DisplayRectangle.Height;
//this.customScrollbar1.LargeChange = customScrollbar1.Maximum / customScrollbar1.Height + test.Height;
//this.customScrollbar1.SmallChange = 15;//when click the arrows
//this.customScrollbar1.Value = Math.Abs(test.AutoScrollPosition.Y);
}
....
You adding picturebox to your test controls, but you not adding test to forms controls
public Form1()
{
InitializeComponent();
UserControl1 test = new UserControl1();
test.BackColor = Color.Transparent;
test.Location = new Point(0, 110);
test.Width = 660;
test.Height = 478;
PictureBox b = new PictureBox();
b.Location = new Point(100, 100);
b.Width = 320;
b.Height = 475;
b.Image = Properties.Resources.movie;
test.Controls.Add(b);
this.Controls.Add(test);//<- here
}

How to make a floating control

I would like to create a control the floats (potentially) outside the bounds of it's containing form. Is this possible? How may I do it?
This would function much like Context Menu's only I need to be able to add other controls to it such as buttons and images.
You want a Form with it's FormBorderStyle set to None, if you want it to behave like a context menu then you'll need to tie showing it to the appropriate event handler in your main form. Simple example below of setting the location and calling show from a mouse click event handler.
MyForm form = new MyForm();
form.Location = PointToScreen(new Point(e.X, e.Y));
form.Show();
It is possible, the TopLevel property controls this. However, the designer doesn't support them well, hard to keep control over controls that are also top-level windows at design time.
Beyond components like ToolTip and ContextMenuStrip, there is exactly one class that is top-level by design, the Form class. Set its FormBorderStyle to None and ControlBox to False to create a basic top-level window that you can use and populate with other controls.
Take a look at the DockPanel Suite source and adopt the technique.
here is u can made for all Control floating Style
private void Panel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Panel.Left += e.X - PanelMouseDownLocation.X;
Panel.Top += e.Y - PanelMouseDownLocation.Y;
}
}
private void Panel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) PanelMouseDownLocation = e.Location;
}
public Point PanelMouseDownLocation { get; set; }
It would need to be a separate window (much like a context menu actually is) -- you could wrap it as a control, that displays a modeless form (which would even give you the option for non rectangular windows if you really wanted to). As you could create the window from a non-visible control from the parent form, you can maintain a reference to the child for handling inter-form communication.
Have your UserControl override CreateParams. For example:
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
cp.ExStyle &= 0x00080000; // WS_EX_LAYERED
cp.Style = 0x40000000 | 0x4000000; // WS_CHILD | WS_CLIPSIBLINGS
cp.Parent = GetDesktopWindow();
return cp;
}
}
This may have unintended effects (including not working well with Designer). I am choosing to follow one of the above patterns, but I thought it was worth mentioning here. Lookup CreateParams to see its purpose. (This option was gleaned from this page.)
This worked for me
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using LollipopUIControls.UIManagers;
namespace Gamasis.Apps.Controls
{
public class FloatingButton : Button
{
public FloatingButton()
{
SetStyle((ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint), true);
DoubleBuffered = true;
Size = new Size(50, 50);
BackColor = Color.Transparent;
SF.Alignment = StringAlignment.Center;
SF.LineAlignment = StringAlignment.Center;
AnimationTimer.Tick += new EventHandler(AnimationTick);
}
#region Variables
Timer AnimationTimer = new Timer { Interval = 1 };
FontManager font = new FontManager();
StringFormat SF = new StringFormat();
Rectangle StringRectangle;
bool Focus = false;
int margintop = 0, marginleft = 0, marginright = 0, marginBottom = 0;
int xx;
int yy;
float SizeAnimation = 0;
float SizeIncNum;
string fontcolor = "#FAFAFA";
string Backcolor = "#039BE5";
Color EnabledBGColor;
Color EnabledBorderColor;
Color StringColor;
Color DisabledBGColor = ColorTranslator.FromHtml("#B0BEC5");
Color DisabledStringColor = ColorTranslator.FromHtml("#FAFAFA");
Color NonColor = ColorTranslator.FromHtml("#e3e5e7");
Image bGImage = null;
#endregion
#region Properties
[Category("Custom")]
public string BGColor
{
get { return Backcolor; }
set
{
Backcolor = value;
Invalidate();
}
}
[Category("Custom")]
public string FontColor
{
get { return fontcolor; }
set
{
fontcolor = value;
Invalidate();
}
}
[Browsable(false)]
public Font Font
{
get { return base.Font; }
set { base.Font = value; }
}
[Browsable(false)]
public Color ForeColor
{
get { return base.ForeColor; }
set { base.ForeColor = value; }
}
[Category("Custom")]
public Image BGImage
{
get { return bGImage; }
set { bGImage = value; }
}
ImageSizeLevel bGimgSize = ImageSizeLevel.peque2;
public ImageSizeLevel BGimgSize
{
get { return bGimgSize; }
set { bGimgSize = value; }
}
#endregion
#region Events
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
EnabledBGColor = Color.FromArgb(30, ColorTranslator.FromHtml(BGColor));//StringColor);
EnabledBorderColor = Color.FromArgb(20, ColorTranslator.FromHtml(BGColor));//StringColor);
Refresh();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
EnabledBGColor = ColorTranslator.FromHtml(BGColor);
EnabledBorderColor = ColorTranslator.FromHtml(BGColor);
Refresh();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
EnabledBGColor = Color.FromArgb(30, StringColor);
Refresh();
xx = e.X;
yy = e.Y;
Focus = true;
AnimationTimer.Start();
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Focus = false;
AnimationTimer.Start();
Invalidate();
}
protected override void OnTextChanged(System.EventArgs e)
{
base.OnTextChanged(e);
Invalidate();
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
//StringRectangle = new Rectangle(3, 0, Width - 6, Height - 6);
}
#endregion
protected override void OnResize(System.EventArgs e)
{
base.OnResize(e);
//SizeIncNum = Width / 34;
SizeIncNum = Width / 10;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var G = e.Graphics;
#region Default rectangle
//G.SmoothingMode = SmoothingMode.HighQuality | SmoothingMode.AntiAlias;
//G.Clear(Parent.BackColor);
//StringColor = ColorTranslator.FromHtml(fontcolor);
//var BG = DrawHelper.CreateRoundRect(1, 1, Width - 3, Height - 3, 1);
//Region region = new Region(BG);
//G.FillPath(new SolidBrush(Enabled ? EnabledBGColor : Color.White), BG);
//G.DrawPath(new Pen(Enabled ? EnabledBorderColor : Color.White), BG);
//G.SetClip(region, CombineMode.Replace);
////The Ripple Effect
//G.FillEllipse(new SolidBrush(Color.FromArgb(30, StringColor)), xx - (SizeAnimation / 2), yy - (SizeAnimation / 2), SizeAnimation, SizeAnimation);
//G.DrawString(Text, font.Roboto_Medium10, new SolidBrush(Enabled ? StringColor : DisabledStringColor), R, SF);
#endregion
#region Circle
//G.SmoothingMode = SmoothingMode.AntiAlias;
//G.Clear(BackColor);
//GraphicsPath bgbtn = new GraphicsPath();
//bgbtn.AddEllipse(0, 0, Width - 5, Height - 5);
//GraphicsPath bgShadow = new GraphicsPath();
//bgShadow.AddEllipse(0, 0, Width - 2, Height - 2);
//G.FillPath(new SolidBrush(NonColor), bgShadow);
//G.DrawPath(new Pen(NonColor), bgShadow);
//G.FillPath(new SolidBrush(Color.DeepSkyBlue), bgbtn);
//G.DrawPath(new Pen(Color.DeepSkyBlue), bgbtn);
#endregion
///----------------------------
G.SmoothingMode = SmoothingMode.AntiAlias;
G.Clear(Parent.BackColor);
StringColor = ColorTranslator.FromHtml(fontcolor);
//var BG = DrawHelper.CreateRoundRect(1, 1, Width - 3, Height - 3, 1);
//Círculo principal
GraphicsPath bgbtn = new GraphicsPath();
bgbtn.AddEllipse(2, 0, Width - 6, Height - 6);
//Círculo para la sombra
GraphicsPath bgShadow = new GraphicsPath();
bgShadow.AddEllipse(2, 4, Width - 6, Height - 6);
// se dibuja la sombra
G.FillPath(new SolidBrush(NonColor), bgShadow);
G.DrawPath(new Pen(NonColor), bgShadow);
//sedibuja el círculo principal sobre la sombra
G.FillPath(new SolidBrush(Enabled ? ColorTranslator.FromHtml(BGColor) : DisabledBGColor), bgbtn);
G.DrawPath(new Pen(Enabled ? ColorTranslator.FromHtml(BGColor) : DisabledBGColor), bgbtn);
// Se da a la región forma de círculo/elipse
Region region = new Region(bgbtn);//BG);
G.SetClip(region, CombineMode.Replace);
//The Ripple Effect
if (Enabled)
G.FillEllipse(new SolidBrush(Color.FromArgb(30, EnabledBGColor)), xx - (SizeAnimation / 2), yy - (SizeAnimation / 2), SizeAnimation, SizeAnimation);
StringRectangle = new Rectangle((int)bgbtn.GetBounds().Location.X, (int)bgbtn.GetBounds().Location.Y,
(int)bgbtn.GetBounds().Size.Width, (int)bgbtn.GetBounds().Size.Height);
G.DrawString(Text, font.Roboto_Medium15, new SolidBrush(Enabled ? StringColor : DisabledStringColor), StringRectangle, SF);
if (bGImage != null)
{
float imgX = 0, imgY = 0;
imgY = (bgbtn.GetBounds().Size.Height - (int)bGimgSize) / 2;
imgX = ((bgbtn.GetBounds().Size.Width - (int)bGimgSize) + 2) / 2;
G.DrawImage(bGImage, imgX, imgY, (float)bGimgSize, (float)bGimgSize);
}
}
protected void AnimationTick(object sender, EventArgs e)
{
if (Focus)
{
if (SizeAnimation < Width + 250)
{
SizeAnimation += SizeIncNum;
this.Invalidate();
}
}
else
{
if (SizeAnimation > 0)
{
SizeAnimation = 0;
this.Invalidate();
}
}
}
public enum ImageSizeLevel
{
peque = 12, peque1 = 24, peque2 = 32,
maso = 48, maso1 = 56, maso2 = 64,
grande = 72, grande1 = 86, grande2 = 96,
monstruo = 128, monstruo1 = 256, monstruo2 = 512
}
}
}

Categories