Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Button icon theme management #169

Merged
merged 1 commit into from
May 7, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 126 additions & 14 deletions MaterialSkin/Controls/MaterialButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Windows.Forms;

Expand All @@ -13,6 +14,15 @@
/// </summary>
public class MaterialButton : Button, IMaterialControl
{
private const int ICON_SIZE = 24;
private const int MINIMUMWIDTH = 88; //64;
private const int MINIMUMWIDTHICONONLY = 36; //64;
private const int HEIGHTDEFAULT = 36;
private const int HEIGHTDENSE = 32;

// icons
private TextureBrush iconsBrushes;

/// <summary>
/// Gets or sets the Depth
/// </summary>
Expand All @@ -38,12 +48,20 @@ public enum MaterialButtonType
Contained
}

public enum MaterialButtonDensity
{
Default,
Dense
}

[Category("Material Skin")]
public bool UseAccentColor
{
get { return useAccentColor; }
set { useAccentColor = value; Invalidate(); }
}

[Category("Material Skin")]
/// <summary>
/// Gets or sets a value indicating whether HighEmphasis
/// </summary>
Expand All @@ -53,21 +71,40 @@ public bool HighEmphasis
set { highEmphasis = value; Invalidate(); }
}

[DefaultValue(true)]
[Category("Material Skin")]
[Description("Draw Shadows around control")]
public bool DrawShadows
{
get { return drawShadows; }
set { drawShadows = value; Invalidate(); }
}

/// <summary>
/// Gets or sets a value indicating whether HighEmphasis
/// </summary>
[Category("Material Skin")]
public MaterialButtonType Type
{
get { return type; }
set { type = value; Invalidate(); }
}

[Category("Material Skin")]
/// <summary>
/// Gets or sets a value indicating button density
/// </summary>
public MaterialButtonDensity Density
{
get { return _density; }
set
{
_density = value;
if (_density== MaterialButtonDensity.Dense)
Size = new Size(Size.Width, HEIGHTDENSE);
else
Size = new Size(Size.Width, HEIGHTDEFAULT);
Invalidate();
}
}

protected override void InitLayout()
{
base.InitLayout();
Expand Down Expand Up @@ -95,6 +132,12 @@ protected override void OnVisibleChanged(EventArgs e)
RemoveShadowPaintEvent(Parent, drawShadowOnParent);
}

protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
Invalidate();
}

private bool _shadowDrawEventSubscribed = false;

private void AddShadowPaintEvent(Control control, PaintEventHandler shadowPaintEvent)
Expand Down Expand Up @@ -130,7 +173,9 @@ private void RemoveShadowPaintEvent(Control control, PaintEventHandler shadowPai
private bool highEmphasis;
private bool useAccentColor;
private MaterialButtonType type;
private MaterialButtonDensity _density;

[Category("Material Skin")]
/// <summary>
/// Gets or sets the Icon
/// </summary>
Expand All @@ -140,6 +185,8 @@ public Image Icon
set
{
_icon = value;
preProcessIcons();

if (AutoSize)
{
Refresh();
Expand All @@ -165,6 +212,7 @@ public MaterialButton()
HighEmphasis = true;
UseAccentColor = false;
Type = MaterialButtonType.Contained;
Density = MaterialButtonDensity.Default;

_animationManager = new AnimationManager(false)
{
Expand All @@ -176,6 +224,15 @@ public MaterialButton()
Increment = 0.12,
AnimationType = AnimationType.Linear
};
SkinManager.ColorSchemeChanged += sender =>
{
preProcessIcons();
};

SkinManager.ThemeChanged += sender =>
{
preProcessIcons();
};

_hoverAnimationManager.OnAnimationProgress += sender => Invalidate();
_animationManager.OnAnimationProgress += sender => Invalidate();
Expand Down Expand Up @@ -222,6 +279,59 @@ private void drawShadowOnParent(object sender, PaintEventArgs e)
DrawHelper.DrawSquareShadow(gp, rect);
}

private void preProcessIcons()
{
if (Icon == null) return;

// Calculate lightness and color
float l = (SkinManager.Theme == MaterialSkinManager.Themes.LIGHT & (highEmphasis == false | Enabled == false | Type != MaterialButtonType.Contained)) ? 0f : 1.5f;

// Create matrices
float[][] matrixGray = {
new float[] { 0, 0, 0, 0, 0}, // Red scale factor
new float[] { 0, 0, 0, 0, 0}, // Green scale factor
new float[] { 0, 0, 0, 0, 0}, // Blue scale factor
new float[] { 0, 0, 0, Enabled ? .7f : .3f, 0}, // alpha scale factor
new float[] { l, l, l, 0, 1}};// offset


ColorMatrix colorMatrixGray = new ColorMatrix(matrixGray);

ImageAttributes grayImageAttributes = new ImageAttributes();

// Set color matrices
grayImageAttributes.SetColorMatrix(colorMatrixGray, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

// Image Rect
Rectangle destRect = new Rectangle(0, 0, ICON_SIZE, ICON_SIZE);

// Create a pre-processed copy of the image (GRAY)
Bitmap bgray = new Bitmap(destRect.Width, destRect.Height);
using (Graphics gGray = Graphics.FromImage(bgray))
{
gGray.DrawImage(Icon,
new Point[] {
new Point(0, 0),
new Point(destRect.Width, 0),
new Point(0, destRect.Height),
},
destRect, GraphicsUnit.Pixel, grayImageAttributes);
}

// added processed image to brush for drawing
TextureBrush textureBrushGray = new TextureBrush(bgray);

textureBrushGray.WrapMode = System.Drawing.Drawing2D.WrapMode.Clamp;

// Translate the brushes to the correct positions
var iconRect = new Rectangle(8, 6, ICON_SIZE, ICON_SIZE);

textureBrushGray.TranslateTransform(iconRect.X + iconRect.Width / 2 - Icon.Width / 2,
iconRect.Y + iconRect.Height / 2 - Icon.Height / 2);

iconsBrushes = textureBrushGray;
}

/// <summary>
/// The OnPaint
/// </summary>
Expand Down Expand Up @@ -278,7 +388,7 @@ protected override void OnPaint(PaintEventArgs pevent)

//Hover
using (SolidBrush hoverBrush = new SolidBrush(Color.FromArgb(
(int)(hoverAnimProgress * SkinManager.BackgroundFocusColor.A), (UseAccentColor ? (HighEmphasis && Type == MaterialButtonType.Contained ?
(int)(HighEmphasis && Type == MaterialButtonType.Contained ? hoverAnimProgress * 80 : hoverAnimProgress * SkinManager.BackgroundFocusColor.A), (UseAccentColor ? (HighEmphasis && Type == MaterialButtonType.Contained ?
SkinManager.ColorScheme.AccentColor.Lighten(0.5f) : // Contained with Emphasis - with accent
SkinManager.ColorScheme.AccentColor) : // Not Contained Or Low Emphasis - with accent
(Type == MaterialButtonType.Contained && HighEmphasis ? SkinManager.ColorScheme.LightPrimaryColor : // Contained with Emphasis without accent
Expand Down Expand Up @@ -322,7 +432,7 @@ protected override void OnPaint(PaintEventArgs pevent)
}

//Icon
var iconRect = new Rectangle(8, 6, 24, 24);
var iconRect = new Rectangle(8, 6, ICON_SIZE, ICON_SIZE);

if (string.IsNullOrEmpty(Text))
{
Expand All @@ -332,27 +442,27 @@ protected override void OnPaint(PaintEventArgs pevent)

if (Icon != null)
{
g.DrawImage(Icon, iconRect);
g.FillRectangle(iconsBrushes, iconRect);
}

//Text
var textRect = ClientRectangle;
if (Icon != null)
{
textRect.Width -= 8 + 24 + 4 + 8; // left padding + icon width + space between Icon and Text + right padding
textRect.X += 8 + 24 + 4; // left padding + icon width + space between Icon and Text
textRect.Width -= 8 + ICON_SIZE + 4 + 8; // left padding + icon width + space between Icon and Text + right padding
textRect.X += 8 + ICON_SIZE + 4; // left padding + icon width + space between Icon and Text
}

Color textColor = Enabled ? (HighEmphasis ? (Type == MaterialButtonType.Text || Type == MaterialButtonType.Outlined) ?
(UseAccentColor ? SkinManager.ColorScheme.AccentColor : // Outline or Text and accent and emphasis
SkinManager.ColorScheme.PrimaryColor) : // Outline or Text and emphasis
SkinManager.Theme == MaterialSkin.MaterialSkinManager.Themes.LIGHT ? SkinManager.ColorScheme.PrimaryColor : SkinManager.ColorScheme.LightPrimaryColor) : // Outline or Text and emphasis
SkinManager.ColorScheme.TextColor : // Contained and Emphasis
SkinManager.TextHighEmphasisColor) : // Cointained and accent
SkinManager.TextDisabledOrHintColor; // Disabled

using (NativeTextRenderer NativeText = new NativeTextRenderer(g))
{
NativeText.DrawTransparentText(Text.ToUpper(), SkinManager.getLogFontByType(MaterialSkinManager.fontType.Button),
NativeText.DrawMultilineTransparentText(Text.ToUpper(), SkinManager.getLogFontByType(MaterialSkinManager.fontType.Button),
textColor,
textRect.Location,
textRect.Size,
Expand Down Expand Up @@ -385,20 +495,22 @@ public override Size GetPreferredSize(Size proposedSize)
{
// 24 is for icon size
// 4 is for the space between icon & text
extra += 24 + 4;
extra += ICON_SIZE + 4;
}

if (AutoSize)
{
s.Width = (int)Math.Ceiling(_textSize.Width);
s.Width += extra;
s.Height = 36;
s.Height = HEIGHTDEFAULT;
}
else
{
s.Width += extra;
s.Height = 36;
s.Height = HEIGHTDEFAULT;
}
if (Icon != null && Text.Length==0 && s.Width < MINIMUMWIDTHICONONLY) s.Width = MINIMUMWIDTHICONONLY;
else if (s.Width < MINIMUMWIDTH) s.Width = MINIMUMWIDTH;

return s;
}
Expand Down Expand Up @@ -465,4 +577,4 @@ protected override void OnCreateControl()
};
}
}
}
}