Files
2025-07-14 12:03:59 +02:00

171 lines
5.3 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Threading.Tasks;
using System.Windows.Forms;
using MaterialSkin.Animations;
namespace MaterialSkin.Controls
{
public class MaterialIcon:Control
{
private Image _image;
private Bitmap _bmp;
private AnimationManager _animationManager;
private Point _lastLocation;
private Bitmap _backBuffer = null;
private bool _primary;
public MaterialIcon()
{
Cursor = Cursors.Hand;
Clickable = true;
_animationManager = new AnimationManager(false)
{
Increment = 0.02,
AnimationType = AnimationType.EaseOut
};
_animationManager.OnAnimationProgress += sender => Invalidate();
_animationManager.OnAnimationFinished += AnimationManagerOnOnAnimationFinished;
}
private void AnimationManagerOnOnAnimationFinished(object sender)
{
}
[Browsable(false)]
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
public Image Image
{
get { return _image; }
set
{
_image = value;
RebuildIcon();
}
}
public bool Primary
{
get { return _primary; }
set
{
_primary = value;
if (_image == null) return;
RebuildIcon();
}
}
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
RebuildIcon();
}
protected override void OnResize(EventArgs e)
{
_backBuffer=new Bitmap(Width,Height);
if (_image == null) return;
RebuildIcon();
base.OnResize(e);
}
private void RebuildIcon()
{
Task.Run(() =>
{
lock (_lockObject)
{
var tmp = new Bitmap(_image);
ReplaceColor(tmp, Color.Black,
Enabled
? (_primary
? SkinManager.GetApplicationBackgroundColor()
: SkinManager.ColorScheme.PrimaryColor)
: Color.FromArgb(0xAA, 0xAA, 0xAA));
_bmp = tmp;
Invalidate();
}
});
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground(pevent);
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
base.OnMouseDown(mevent);
if (!Enabled) return;
_lastLocation = mevent.Location;
_animationManager.StartNewAnimation(AnimationDirection.In, _lastLocation);
}
public bool Clickable { get; set; }
protected override void OnClick(EventArgs e)
{
if (!Clickable) return;
base.OnClick(e);
}
protected override void OnPaint(PaintEventArgs pe)
{
if (Image == null) return;
if(_bmp == null)return;
if(_backBuffer==null)return;
using (Graphics g=Graphics.FromImage(_backBuffer))
{
g.InterpolationMode = InterpolationMode.Bicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.Clear(_primary? SkinManager.ColorScheme.PrimaryColor : SkinManager.GetApplicationBackgroundColor());
if (_animationManager.IsAnimating())
{
for (int i = 0; i < _animationManager.GetAnimationCount(); i++)
{
var animationValue = _animationManager.GetProgress(i);
var animationSource = _animationManager.GetSource(i);
var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), _primary ? SkinManager.GetApplicationBackgroundColor() : SkinManager.ColorScheme.PrimaryColor));
var rippleSize = (int)(animationValue * Width * 2);
g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
}
}
g.DrawImage(_bmp,1,1,Width-2,Height-2);
}
pe.Graphics.DrawImage(_backBuffer, 0,0);
}
object _lockObject = new object();
private void ReplaceColor(Bitmap bmp, Color oldColor, Color newColor)
{
{
var lockedBitmap = bmp;
for (int y = 0; y < lockedBitmap.Height; y++)
{
for (int x = 0; x < lockedBitmap.Width; x++)
{
if (lockedBitmap.GetPixel(x, y).A > 0)
{
lockedBitmap.SetPixel(x, y, newColor);
}
}
}
}
}
}
}