check point
This commit is contained in:
12
framework/MaterialSkin.Core/Animations/AnimationDirection.cs
Normal file
12
framework/MaterialSkin.Core/Animations/AnimationDirection.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace MaterialSkin.Animations
|
||||
{
|
||||
enum AnimationDirection
|
||||
{
|
||||
In, //In. Stops if finished.
|
||||
Out, //Out. Stops if finished.
|
||||
InOutIn, //Same as In, but changes to InOutOut if finished.
|
||||
InOutOut, //Same as Out.
|
||||
InOutRepeatingIn, // Same as In, but changes to InOutRepeatingOut if finished.
|
||||
InOutRepeatingOut // Same as Out, but changes to InOutRepeatingIn if finished.
|
||||
}
|
||||
}
|
||||
363
framework/MaterialSkin.Core/Animations/AnimationManager.cs
Normal file
363
framework/MaterialSkin.Core/Animations/AnimationManager.cs
Normal file
@@ -0,0 +1,363 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Animations
|
||||
{
|
||||
class AnimationManager
|
||||
{
|
||||
public bool InterruptAnimation { get; set; }
|
||||
public double Increment { get; set; }
|
||||
public double SecondaryIncrement { get; set; }
|
||||
public AnimationType AnimationType { get; set; }
|
||||
public bool Singular { get; set; }
|
||||
|
||||
public delegate void AnimationFinished(object sender);
|
||||
public event AnimationFinished OnAnimationFinished;
|
||||
|
||||
public delegate void AnimationProgress(object sender);
|
||||
public event AnimationProgress OnAnimationProgress;
|
||||
|
||||
private readonly List<double> _animationProgresses;
|
||||
private readonly List<Point> _animationSources;
|
||||
private readonly List<AnimationDirection> _animationDirections;
|
||||
private readonly List<object[]> _animationDatas;
|
||||
|
||||
private const double MIN_VALUE = 0.00;
|
||||
private const double MAX_VALUE = 1.00;
|
||||
|
||||
private readonly Timer _animationTimer = new Timer { Interval = 5, Enabled = false };
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="singular">If true, only one animation is supported. The current animation will be replaced with the new one. If false, a new animation is added to the list.</param>
|
||||
public AnimationManager(bool singular = true)
|
||||
{
|
||||
_animationProgresses = new List<double>();
|
||||
_animationSources = new List<Point>();
|
||||
_animationDirections = new List<AnimationDirection>();
|
||||
_animationDatas = new List<object[]>();
|
||||
|
||||
Increment = 0.03;
|
||||
SecondaryIncrement = 0.03;
|
||||
AnimationType = AnimationType.Linear;
|
||||
InterruptAnimation = true;
|
||||
Singular = singular;
|
||||
|
||||
if (Singular)
|
||||
{
|
||||
_animationProgresses.Add(0);
|
||||
_animationSources.Add(new Point(0, 0));
|
||||
_animationDirections.Add(AnimationDirection.In);
|
||||
}
|
||||
|
||||
_animationTimer.Tick += AnimationTimerOnTick;
|
||||
}
|
||||
|
||||
private void AnimationTimerOnTick(object sender, EventArgs eventArgs)
|
||||
{
|
||||
for (var i = 0; i < _animationProgresses.Count; i++)
|
||||
{
|
||||
UpdateProgress(i);
|
||||
|
||||
if (!Singular)
|
||||
{
|
||||
if ((_animationDirections[i] == AnimationDirection.InOutIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingIn && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingIn;
|
||||
}
|
||||
else if (
|
||||
(_animationDirections[i] == AnimationDirection.In && _animationProgresses[i] == MAX_VALUE) ||
|
||||
(_animationDirections[i] == AnimationDirection.Out && _animationProgresses[i] == MIN_VALUE) ||
|
||||
(_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationProgresses.RemoveAt(i);
|
||||
_animationSources.RemoveAt(i);
|
||||
_animationDirections.RemoveAt(i);
|
||||
_animationDatas.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_animationDirections[i] == AnimationDirection.InOutIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingIn && _animationProgresses[i] == MAX_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingOut;
|
||||
}
|
||||
else if ((_animationDirections[i] == AnimationDirection.InOutRepeatingOut && _animationProgresses[i] == MIN_VALUE))
|
||||
{
|
||||
_animationDirections[i] = AnimationDirection.InOutRepeatingIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnAnimationProgress?.Invoke(this);
|
||||
}
|
||||
|
||||
public bool IsAnimating()
|
||||
{
|
||||
return _animationTimer.Enabled;
|
||||
}
|
||||
|
||||
public void StartNewAnimation(AnimationDirection animationDirection, object[] data = null)
|
||||
{
|
||||
StartNewAnimation(animationDirection, new Point(0, 0), data);
|
||||
}
|
||||
|
||||
public void StartNewAnimation(AnimationDirection animationDirection, Point animationSource, object[] data = null)
|
||||
{
|
||||
if (!IsAnimating() || InterruptAnimation)
|
||||
{
|
||||
if (Singular && _animationDirections.Count > 0)
|
||||
{
|
||||
_animationDirections[0] = animationDirection;
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationDirections.Add(animationDirection);
|
||||
}
|
||||
|
||||
if (Singular && _animationSources.Count > 0)
|
||||
{
|
||||
_animationSources[0] = animationSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationSources.Add(animationSource);
|
||||
}
|
||||
|
||||
if (!(Singular && _animationProgresses.Count > 0))
|
||||
{
|
||||
switch (_animationDirections[_animationDirections.Count - 1])
|
||||
{
|
||||
case AnimationDirection.InOutRepeatingIn:
|
||||
case AnimationDirection.InOutIn:
|
||||
case AnimationDirection.In:
|
||||
_animationProgresses.Add(MIN_VALUE);
|
||||
break;
|
||||
case AnimationDirection.InOutRepeatingOut:
|
||||
case AnimationDirection.InOutOut:
|
||||
case AnimationDirection.Out:
|
||||
_animationProgresses.Add(MAX_VALUE);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid AnimationDirection");
|
||||
}
|
||||
}
|
||||
|
||||
if (Singular && _animationDatas.Count > 0)
|
||||
{
|
||||
_animationDatas[0] = data ?? new object[] { };
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationDatas.Add(data ?? new object[] { });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_animationTimer.Start();
|
||||
}
|
||||
|
||||
public void UpdateProgress(int index)
|
||||
{
|
||||
switch (_animationDirections[index])
|
||||
{
|
||||
case AnimationDirection.InOutRepeatingIn:
|
||||
case AnimationDirection.InOutIn:
|
||||
case AnimationDirection.In:
|
||||
IncrementProgress(index);
|
||||
break;
|
||||
case AnimationDirection.InOutRepeatingOut:
|
||||
case AnimationDirection.InOutOut:
|
||||
case AnimationDirection.Out:
|
||||
DecrementProgress(index);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No AnimationDirection has been set");
|
||||
}
|
||||
}
|
||||
|
||||
private void IncrementProgress(int index)
|
||||
{
|
||||
_animationProgresses[index] += Increment;
|
||||
if (_animationProgresses[index] > MAX_VALUE)
|
||||
{
|
||||
_animationProgresses[index] = MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < GetAnimationCount(); i++)
|
||||
{
|
||||
if (_animationDirections[i] == AnimationDirection.InOutIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingOut) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] != MAX_VALUE) return;
|
||||
if (_animationDirections[i] == AnimationDirection.In && _animationProgresses[i] != MAX_VALUE) return;
|
||||
}
|
||||
|
||||
_animationTimer.Stop();
|
||||
OnAnimationFinished?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void DecrementProgress(int index)
|
||||
{
|
||||
_animationProgresses[index] -= (_animationDirections[index] == AnimationDirection.InOutOut || _animationDirections[index] == AnimationDirection.InOutRepeatingOut) ? SecondaryIncrement : Increment;
|
||||
if (_animationProgresses[index] < MIN_VALUE)
|
||||
{
|
||||
_animationProgresses[index] = MIN_VALUE;
|
||||
|
||||
for (var i = 0; i < GetAnimationCount(); i++)
|
||||
{
|
||||
if (_animationDirections[i] == AnimationDirection.InOutIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingIn) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutRepeatingOut) return;
|
||||
if (_animationDirections[i] == AnimationDirection.InOutOut && _animationProgresses[i] != MIN_VALUE) return;
|
||||
if (_animationDirections[i] == AnimationDirection.Out && _animationProgresses[i] != MIN_VALUE) return;
|
||||
}
|
||||
|
||||
_animationTimer.Stop();
|
||||
OnAnimationFinished?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
public double GetProgress()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return GetProgress(0);
|
||||
}
|
||||
|
||||
public double GetProgress(int index)
|
||||
{
|
||||
if (!(index < GetAnimationCount()))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
switch (AnimationType)
|
||||
{
|
||||
case AnimationType.Linear:
|
||||
return AnimationLinear.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.EaseInOut:
|
||||
return AnimationEaseInOut.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.EaseOut:
|
||||
return AnimationEaseOut.CalculateProgress(_animationProgresses[index]);
|
||||
case AnimationType.CustomQuadratic:
|
||||
return AnimationCustomQuadratic.CalculateProgress(_animationProgresses[index]);
|
||||
default:
|
||||
throw new NotImplementedException("The given AnimationType is not implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Point GetSource(int index)
|
||||
{
|
||||
if (!(index < GetAnimationCount()))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationSources[index];
|
||||
}
|
||||
|
||||
public Point GetSource()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationSources.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationSources[0];
|
||||
}
|
||||
|
||||
public AnimationDirection GetDirection()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDirections.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationDirections[0];
|
||||
}
|
||||
|
||||
public AnimationDirection GetDirection(int index)
|
||||
{
|
||||
if (!(index < _animationDirections.Count))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationDirections[index];
|
||||
}
|
||||
|
||||
public object[] GetData()
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDatas.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
return _animationDatas[0];
|
||||
}
|
||||
|
||||
public object[] GetData(int index)
|
||||
{
|
||||
if (!(index < _animationDatas.Count))
|
||||
throw new IndexOutOfRangeException("Invalid animation index");
|
||||
|
||||
return _animationDatas[index];
|
||||
}
|
||||
|
||||
public int GetAnimationCount()
|
||||
{
|
||||
return _animationProgresses.Count;
|
||||
}
|
||||
|
||||
public void SetProgress(double progress)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationProgresses[0] = progress;
|
||||
}
|
||||
|
||||
public void SetDirection(AnimationDirection direction)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationProgresses.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationDirections[0] = direction;
|
||||
}
|
||||
|
||||
public void SetData(object[] data)
|
||||
{
|
||||
if (!Singular)
|
||||
throw new Exception("Animation is not set to Singular.");
|
||||
|
||||
if (_animationDatas.Count == 0)
|
||||
throw new Exception("Invalid animation");
|
||||
|
||||
_animationDatas[0] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
framework/MaterialSkin.Core/Animations/Animations.cs
Normal file
53
framework/MaterialSkin.Core/Animations/Animations.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace MaterialSkin.Animations
|
||||
{
|
||||
enum AnimationType
|
||||
{
|
||||
Linear,
|
||||
EaseInOut,
|
||||
EaseOut,
|
||||
CustomQuadratic
|
||||
}
|
||||
|
||||
static class AnimationLinear
|
||||
{
|
||||
public static double CalculateProgress(double progress)
|
||||
{
|
||||
return progress;
|
||||
}
|
||||
}
|
||||
|
||||
static class AnimationEaseInOut
|
||||
{
|
||||
public static double PI = Math.PI;
|
||||
public static double PI_HALF = Math.PI / 2;
|
||||
|
||||
public static double CalculateProgress(double progress)
|
||||
{
|
||||
return EaseInOut(progress);
|
||||
}
|
||||
|
||||
private static double EaseInOut(double s)
|
||||
{
|
||||
return s - Math.Sin(s * 2 * PI) / (2 * PI);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnimationEaseOut
|
||||
{
|
||||
public static double CalculateProgress(double progress)
|
||||
{
|
||||
return -1 * progress * (progress - 2);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnimationCustomQuadratic
|
||||
{
|
||||
public static double CalculateProgress(double progress)
|
||||
{
|
||||
var kickoff = 0.6;
|
||||
return 1 - Math.Cos((Math.Max(progress, kickoff) - kickoff) * Math.PI / (2 - (2 * kickoff)));
|
||||
}
|
||||
}
|
||||
}
|
||||
371
framework/MaterialSkin.Core/ColorScheme.cs
Normal file
371
framework/MaterialSkin.Core/ColorScheme.cs
Normal file
@@ -0,0 +1,371 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace MaterialSkin
|
||||
{
|
||||
public class ColorScheme
|
||||
{
|
||||
public readonly Color PrimaryColor, DarkPrimaryColor, LightPrimaryColor, AccentColor, TextColor;
|
||||
public readonly Pen PrimaryPen, DarkPrimaryPen, LightPrimaryPen, AccentPen, TextPen;
|
||||
public readonly Brush PrimaryBrush, DarkPrimaryBrush, LightPrimaryBrush, AccentBrush, TextBrush;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Color Scheme to be used for all forms.
|
||||
/// </summary>
|
||||
/// <param name="primary">The primary color, a -500 color is suggested here.</param>
|
||||
/// <param name="darkPrimary">A darker version of the primary color, a -700 color is suggested here.</param>
|
||||
/// <param name="lightPrimary">A lighter version of the primary color, a -100 color is suggested here.</param>
|
||||
/// <param name="accent">The accent color, a -200 color is suggested here.</param>
|
||||
/// <param name="textShade">The text color, the one with the highest contrast is suggested.</param>
|
||||
public ColorScheme(Primary primary, Primary darkPrimary, Primary lightPrimary, Accent accent, TextShade textShade)
|
||||
{
|
||||
//Color
|
||||
PrimaryColor = ((int)primary).ToColor();
|
||||
DarkPrimaryColor = ((int)darkPrimary).ToColor();
|
||||
LightPrimaryColor = ((int)lightPrimary).ToColor();
|
||||
AccentColor = ((int)accent).ToColor();
|
||||
TextColor = ((int)textShade).ToColor();
|
||||
|
||||
//Pen
|
||||
PrimaryPen = new Pen(PrimaryColor);
|
||||
DarkPrimaryPen = new Pen(DarkPrimaryColor);
|
||||
LightPrimaryPen = new Pen(LightPrimaryColor);
|
||||
AccentPen = new Pen(AccentColor);
|
||||
TextPen = new Pen(TextColor);
|
||||
|
||||
//Brush
|
||||
PrimaryBrush = new SolidBrush(PrimaryColor);
|
||||
DarkPrimaryBrush = new SolidBrush(DarkPrimaryColor);
|
||||
LightPrimaryBrush = new SolidBrush(LightPrimaryColor);
|
||||
AccentBrush = new SolidBrush(AccentColor);
|
||||
TextBrush = new SolidBrush(TextColor);
|
||||
}
|
||||
|
||||
public ColorScheme(int primary, int darkPrimary, int lightPrimary, Accent accent, TextShade textShade)
|
||||
{
|
||||
//Color
|
||||
PrimaryColor = ((int)primary).ToColor();
|
||||
DarkPrimaryColor = ((int)darkPrimary).ToColor();
|
||||
LightPrimaryColor = ((int)lightPrimary).ToColor();
|
||||
AccentColor = ((int)accent).ToColor();
|
||||
TextColor = ((int)textShade).ToColor();
|
||||
|
||||
//Pen
|
||||
PrimaryPen = new Pen(PrimaryColor);
|
||||
DarkPrimaryPen = new Pen(DarkPrimaryColor);
|
||||
LightPrimaryPen = new Pen(LightPrimaryColor);
|
||||
AccentPen = new Pen(AccentColor);
|
||||
TextPen = new Pen(TextColor);
|
||||
|
||||
//Brush
|
||||
PrimaryBrush = new SolidBrush(PrimaryColor);
|
||||
DarkPrimaryBrush = new SolidBrush(DarkPrimaryColor);
|
||||
LightPrimaryBrush = new SolidBrush(LightPrimaryColor);
|
||||
AccentBrush = new SolidBrush(AccentColor);
|
||||
TextBrush = new SolidBrush(TextColor);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ColorExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert an integer number to a Color.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Color ToColor(this int argb)
|
||||
{
|
||||
return Color.FromArgb(
|
||||
(argb & 0xff0000) >> 16,
|
||||
(argb & 0xff00) >> 8,
|
||||
argb & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the alpha component of a color.
|
||||
/// </summary>
|
||||
/// <param name="color"></param>
|
||||
/// <returns></returns>
|
||||
public static Color RemoveAlpha(this Color color)
|
||||
{
|
||||
return Color.FromArgb(color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a 0-100 integer to a 0-255 color component.
|
||||
/// </summary>
|
||||
/// <param name="percentage"></param>
|
||||
/// <returns></returns>
|
||||
public static int PercentageToColorComponent(this int percentage)
|
||||
{
|
||||
return (int)((percentage / 100d) * 255d);
|
||||
}
|
||||
}
|
||||
|
||||
//Color constantes
|
||||
public enum TextShade
|
||||
{
|
||||
WHITE = 0xFFFFFF,
|
||||
BLACK = 0x212121
|
||||
}
|
||||
|
||||
public enum Primary
|
||||
{
|
||||
Red50 = 0xFFEBEE,
|
||||
Red100 = 0xFFCDD2,
|
||||
Red200 = 0xEF9A9A,
|
||||
Red300 = 0xE57373,
|
||||
Red400 = 0xEF5350,
|
||||
Red500 = 0xF44336,
|
||||
Red600 = 0xE53935,
|
||||
Red700 = 0xD32F2F,
|
||||
Red800 = 0xC62828,
|
||||
Red900 = 0xB71C1C,
|
||||
Pink50 = 0xFCE4EC,
|
||||
Pink100 = 0xF8BBD0,
|
||||
Pink200 = 0xF48FB1,
|
||||
Pink300 = 0xF06292,
|
||||
Pink400 = 0xEC407A,
|
||||
Pink500 = 0xE91E63,
|
||||
Pink600 = 0xD81B60,
|
||||
Pink700 = 0xC2185B,
|
||||
Pink800 = 0xAD1457,
|
||||
Pink900 = 0x880E4F,
|
||||
Purple50 = 0xF3E5F5,
|
||||
Purple100 = 0xE1BEE7,
|
||||
Purple200 = 0xCE93D8,
|
||||
Purple300 = 0xBA68C8,
|
||||
Purple400 = 0xAB47BC,
|
||||
Purple500 = 0x9C27B0,
|
||||
Purple600 = 0x8E24AA,
|
||||
Purple700 = 0x7B1FA2,
|
||||
Purple800 = 0x6A1B9A,
|
||||
Purple900 = 0x4A148C,
|
||||
DeepPurple50 = 0xEDE7F6,
|
||||
DeepPurple100 = 0xD1C4E9,
|
||||
DeepPurple200 = 0xB39DDB,
|
||||
DeepPurple300 = 0x9575CD,
|
||||
DeepPurple400 = 0x7E57C2,
|
||||
DeepPurple500 = 0x673AB7,
|
||||
DeepPurple600 = 0x5E35B1,
|
||||
DeepPurple700 = 0x512DA8,
|
||||
DeepPurple800 = 0x4527A0,
|
||||
DeepPurple900 = 0x311B92,
|
||||
Indigo50 = 0xE8EAF6,
|
||||
Indigo100 = 0xC5CAE9,
|
||||
Indigo200 = 0x9FA8DA,
|
||||
Indigo300 = 0x7986CB,
|
||||
Indigo400 = 0x5C6BC0,
|
||||
Indigo500 = 0x3F51B5,
|
||||
Indigo600 = 0x3949AB,
|
||||
Indigo700 = 0x303F9F,
|
||||
Indigo800 = 0x283593,
|
||||
Indigo900 = 0x1A237E,
|
||||
Blue50 = 0xE3F2FD,
|
||||
Blue100 = 0xBBDEFB,
|
||||
Blue200 = 0x90CAF9,
|
||||
Blue300 = 0x64B5F6,
|
||||
Blue400 = 0x42A5F5,
|
||||
Blue500 = 0x2196F3,
|
||||
Blue600 = 0x1E88E5,
|
||||
Blue700 = 0x1976D2,
|
||||
Blue800 = 0x1565C0,
|
||||
Blue900 = 0x0D47A1,
|
||||
LightBlue50 = 0xE1F5FE,
|
||||
LightBlue100 = 0xB3E5FC,
|
||||
LightBlue200 = 0x81D4FA,
|
||||
LightBlue300 = 0x4FC3F7,
|
||||
LightBlue400 = 0x29B6F6,
|
||||
LightBlue500 = 0x03A9F4,
|
||||
LightBlue600 = 0x039BE5,
|
||||
LightBlue700 = 0x0288D1,
|
||||
LightBlue800 = 0x0277BD,
|
||||
LightBlue900 = 0x01579B,
|
||||
Cyan50 = 0xE0F7FA,
|
||||
Cyan100 = 0xB2EBF2,
|
||||
Cyan200 = 0x80DEEA,
|
||||
Cyan300 = 0x4DD0E1,
|
||||
Cyan400 = 0x26C6DA,
|
||||
Cyan500 = 0x00BCD4,
|
||||
Cyan600 = 0x00ACC1,
|
||||
Cyan700 = 0x0097A7,
|
||||
Cyan800 = 0x00838F,
|
||||
Cyan900 = 0x006064,
|
||||
Teal50 = 0xE0F2F1,
|
||||
Teal100 = 0xB2DFDB,
|
||||
Teal200 = 0x80CBC4,
|
||||
Teal300 = 0x4DB6AC,
|
||||
Teal400 = 0x26A69A,
|
||||
Teal500 = 0x009688,
|
||||
Teal600 = 0x00897B,
|
||||
Teal700 = 0x00796B,
|
||||
Teal800 = 0x00695C,
|
||||
Teal900 = 0x004D40,
|
||||
Green50 = 0xE8F5E9,
|
||||
Green100 = 0xC8E6C9,
|
||||
Green200 = 0xA5D6A7,
|
||||
Green300 = 0x81C784,
|
||||
Green400 = 0x66BB6A,
|
||||
Green500 = 0x4CAF50,
|
||||
Green600 = 0x43A047,
|
||||
Green700 = 0x388E3C,
|
||||
Green800 = 0x2E7D32,
|
||||
Green900 = 0x1B5E20,
|
||||
LightGreen50 = 0xF1F8E9,
|
||||
LightGreen100 = 0xDCEDC8,
|
||||
LightGreen200 = 0xC5E1A5,
|
||||
LightGreen300 = 0xAED581,
|
||||
LightGreen400 = 0x9CCC65,
|
||||
LightGreen500 = 0x8BC34A,
|
||||
LightGreen600 = 0x7CB342,
|
||||
LightGreen700 = 0x689F38,
|
||||
LightGreen800 = 0x558B2F,
|
||||
LightGreen900 = 0x33691E,
|
||||
Lime50 = 0xF9FBE7,
|
||||
Lime100 = 0xF0F4C3,
|
||||
Lime200 = 0xE6EE9C,
|
||||
Lime300 = 0xDCE775,
|
||||
Lime400 = 0xD4E157,
|
||||
Lime500 = 0xCDDC39,
|
||||
Lime600 = 0xC0CA33,
|
||||
Lime700 = 0xAFB42B,
|
||||
Lime800 = 0x9E9D24,
|
||||
Lime900 = 0x827717,
|
||||
Yellow50 = 0xFFFDE7,
|
||||
Yellow100 = 0xFFF9C4,
|
||||
Yellow200 = 0xFFF59D,
|
||||
Yellow300 = 0xFFF176,
|
||||
Yellow400 = 0xFFEE58,
|
||||
Yellow500 = 0xFFEB3B,
|
||||
Yellow600 = 0xFDD835,
|
||||
Yellow700 = 0xFBC02D,
|
||||
Yellow800 = 0xF9A825,
|
||||
Yellow900 = 0xF57F17,
|
||||
Amber50 = 0xFFF8E1,
|
||||
Amber100 = 0xFFECB3,
|
||||
Amber200 = 0xFFE082,
|
||||
Amber300 = 0xFFD54F,
|
||||
Amber400 = 0xFFCA28,
|
||||
Amber500 = 0xFFC107,
|
||||
Amber600 = 0xFFB300,
|
||||
Amber700 = 0xFFA000,
|
||||
Amber800 = 0xFF8F00,
|
||||
Amber900 = 0xFF6F00,
|
||||
Orange50 = 0xFFF3E0,
|
||||
Orange100 = 0xFFE0B2,
|
||||
Orange200 = 0xFFCC80,
|
||||
Orange300 = 0xFFB74D,
|
||||
Orange400 = 0xFFA726,
|
||||
Orange500 = 0xFF9800,
|
||||
Orange600 = 0xFB8C00,
|
||||
Orange700 = 0xF57C00,
|
||||
Orange800 = 0xEF6C00,
|
||||
Orange900 = 0xE65100,
|
||||
DeepOrange50 = 0xFBE9E7,
|
||||
DeepOrange100 = 0xFFCCBC,
|
||||
DeepOrange200 = 0xFFAB91,
|
||||
DeepOrange300 = 0xFF8A65,
|
||||
DeepOrange400 = 0xFF7043,
|
||||
DeepOrange500 = 0xFF5722,
|
||||
DeepOrange600 = 0xF4511E,
|
||||
DeepOrange700 = 0xE64A19,
|
||||
DeepOrange800 = 0xD84315,
|
||||
DeepOrange900 = 0xBF360C,
|
||||
Brown50 = 0xEFEBE9,
|
||||
Brown100 = 0xD7CCC8,
|
||||
Brown200 = 0xBCAAA4,
|
||||
Brown300 = 0xA1887F,
|
||||
Brown400 = 0x8D6E63,
|
||||
Brown500 = 0x795548,
|
||||
Brown600 = 0x6D4C41,
|
||||
Brown700 = 0x5D4037,
|
||||
Brown800 = 0x4E342E,
|
||||
Brown900 = 0x3E2723,
|
||||
Grey50 = 0xFAFAFA,
|
||||
Grey100 = 0xF5F5F5,
|
||||
Grey200 = 0xEEEEEE,
|
||||
Grey300 = 0xE0E0E0,
|
||||
Grey400 = 0xBDBDBD,
|
||||
Grey500 = 0x9E9E9E,
|
||||
Grey600 = 0x757575,
|
||||
Grey700 = 0x616161,
|
||||
Grey800 = 0x424242,
|
||||
Grey900 = 0x212121,
|
||||
BlueGrey50 = 0xECEFF1,
|
||||
BlueGrey100 = 0xCFD8DC,
|
||||
BlueGrey200 = 0xB0BEC5,
|
||||
BlueGrey300 = 0x90A4AE,
|
||||
BlueGrey400 = 0x78909C,
|
||||
BlueGrey500 = 0x607D8B,
|
||||
BlueGrey600 = 0x546E7A,
|
||||
BlueGrey700 = 0x455A64,
|
||||
BlueGrey800 = 0x37474F,
|
||||
BlueGrey900 = 0x263238
|
||||
}
|
||||
|
||||
public enum Accent
|
||||
{
|
||||
Red100 = 0xFF8A80,
|
||||
Red200 = 0xFF5252,
|
||||
Red400 = 0xFF1744,
|
||||
Red700 = 0xD50000,
|
||||
Pink100 = 0xFF80AB,
|
||||
Pink200 = 0xFF4081,
|
||||
Pink400 = 0xF50057,
|
||||
Pink700 = 0xC51162,
|
||||
Purple100 = 0xEA80FC,
|
||||
Purple200 = 0xE040FB,
|
||||
Purple400 = 0xD500F9,
|
||||
Purple700 = 0xAA00FF,
|
||||
DeepPurple100 = 0xB388FF,
|
||||
DeepPurple200 = 0x7C4DFF,
|
||||
DeepPurple400 = 0x651FFF,
|
||||
DeepPurple700 = 0x6200EA,
|
||||
Indigo100 = 0x8C9EFF,
|
||||
Indigo200 = 0x536DFE,
|
||||
Indigo400 = 0x3D5AFE,
|
||||
Indigo700 = 0x304FFE,
|
||||
Blue100 = 0x82B1FF,
|
||||
Blue200 = 0x448AFF,
|
||||
Blue400 = 0x2979FF,
|
||||
Blue700 = 0x2962FF,
|
||||
LightBlue100 = 0x80D8FF,
|
||||
LightBlue200 = 0x40C4FF,
|
||||
LightBlue400 = 0x00B0FF,
|
||||
LightBlue700 = 0x0091EA,
|
||||
Cyan100 = 0x84FFFF,
|
||||
Cyan200 = 0x18FFFF,
|
||||
Cyan400 = 0x00E5FF,
|
||||
Cyan700 = 0x00B8D4,
|
||||
Teal100 = 0xA7FFEB,
|
||||
Teal200 = 0x64FFDA,
|
||||
Teal400 = 0x1DE9B6,
|
||||
Teal700 = 0x00BFA5,
|
||||
Green100 = 0xB9F6CA,
|
||||
Green200 = 0x69F0AE,
|
||||
Green400 = 0x00E676,
|
||||
Green700 = 0x00C853,
|
||||
LightGreen100 = 0xCCFF90,
|
||||
LightGreen200 = 0xB2FF59,
|
||||
LightGreen400 = 0x76FF03,
|
||||
LightGreen700 = 0x64DD17,
|
||||
Lime100 = 0xF4FF81,
|
||||
Lime200 = 0xEEFF41,
|
||||
Lime400 = 0xC6FF00,
|
||||
Lime700 = 0xAEEA00,
|
||||
Yellow100 = 0xFFFF8D,
|
||||
Yellow200 = 0xFFFF00,
|
||||
Yellow400 = 0xFFEA00,
|
||||
Yellow700 = 0xFFD600,
|
||||
Amber100 = 0xFFE57F,
|
||||
Amber200 = 0xFFD740,
|
||||
Amber400 = 0xFFC400,
|
||||
Amber700 = 0xFFAB00,
|
||||
Orange100 = 0xFFD180,
|
||||
Orange200 = 0xFFAB40,
|
||||
Orange400 = 0xFF9100,
|
||||
Orange700 = 0xFF6D00,
|
||||
DeepOrange100 = 0xFF9E80,
|
||||
DeepOrange200 = 0xFF6E40,
|
||||
DeepOrange400 = 0xFF3D00,
|
||||
DeepOrange700 = 0xDD2C00
|
||||
}
|
||||
}
|
||||
250
framework/MaterialSkin.Core/Controls/MaterialCheckBox.cs
Normal file
250
framework/MaterialSkin.Core/Controls/MaterialCheckBox.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialCheckBox : CheckBox, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
[Browsable(false)]
|
||||
public Point MouseLocation { get; set; }
|
||||
|
||||
private bool _ripple;
|
||||
[Category("Behavior")]
|
||||
public bool Ripple
|
||||
{
|
||||
get { return _ripple; }
|
||||
set
|
||||
{
|
||||
_ripple = value;
|
||||
AutoSize = AutoSize; //Make AutoSize directly set the bounds.
|
||||
|
||||
if (value)
|
||||
{
|
||||
Margin = new Padding(0);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly AnimationManager _animationManager;
|
||||
private readonly AnimationManager _rippleAnimationManager;
|
||||
|
||||
private const int CHECKBOX_SIZE = 18;
|
||||
private const int CHECKBOX_SIZE_HALF = CHECKBOX_SIZE / 2;
|
||||
private const int CHECKBOX_INNER_BOX_SIZE = CHECKBOX_SIZE - 4;
|
||||
|
||||
private int _boxOffset;
|
||||
private Rectangle _boxRectangle;
|
||||
|
||||
public MaterialCheckBox()
|
||||
{
|
||||
_animationManager = new AnimationManager
|
||||
{
|
||||
AnimationType = AnimationType.EaseInOut,
|
||||
Increment = 0.05
|
||||
};
|
||||
_rippleAnimationManager = new AnimationManager(false)
|
||||
{
|
||||
AnimationType = AnimationType.Linear,
|
||||
Increment = 0.10,
|
||||
SecondaryIncrement = 0.08
|
||||
};
|
||||
_animationManager.OnAnimationProgress += sender => Invalidate();
|
||||
_rippleAnimationManager.OnAnimationProgress += sender => Invalidate();
|
||||
|
||||
CheckedChanged += (sender, args) =>
|
||||
{
|
||||
_animationManager.StartNewAnimation(Checked ? AnimationDirection.In : AnimationDirection.Out);
|
||||
};
|
||||
|
||||
Ripple = true;
|
||||
MouseLocation = new Point(-1, -1);
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged(EventArgs e)
|
||||
{
|
||||
base.OnSizeChanged(e);
|
||||
|
||||
_boxOffset = Height / 2 - 9;
|
||||
_boxRectangle = new Rectangle(_boxOffset, _boxOffset, CHECKBOX_SIZE - 1, CHECKBOX_SIZE - 1);
|
||||
}
|
||||
|
||||
public override Size GetPreferredSize(Size proposedSize)
|
||||
{
|
||||
var w = _boxOffset + CHECKBOX_SIZE + 2 + (int)CreateGraphics().MeasureString(Text, SkinManager.ROBOTO_MEDIUM_10).Width;
|
||||
return Ripple ? new Size(w, 30) : new Size(w, 20);
|
||||
}
|
||||
|
||||
private static readonly Point[] CheckmarkLine = { new Point(3, 8), new Point(7, 12), new Point(14, 5) };
|
||||
private const int TEXT_OFFSET = 22;
|
||||
protected override void OnPaint(PaintEventArgs pevent)
|
||||
{
|
||||
var g = pevent.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
// clear the control
|
||||
g.Clear(Parent.BackColor);
|
||||
|
||||
var CHECKBOX_CENTER = _boxOffset + CHECKBOX_SIZE_HALF - 1;
|
||||
|
||||
var animationProgress = _animationManager.GetProgress();
|
||||
|
||||
var colorAlpha = Enabled ? (int)(animationProgress * 255.0) : SkinManager.GetCheckBoxOffDisabledColor().A;
|
||||
var backgroundAlpha = Enabled ? (int)(SkinManager.GetCheckboxOffColor().A * (1.0 - animationProgress)) : SkinManager.GetCheckBoxOffDisabledColor().A;
|
||||
|
||||
var brush = new SolidBrush(Color.FromArgb(colorAlpha, Enabled ? SkinManager.ColorScheme.AccentColor : SkinManager.GetCheckBoxOffDisabledColor()));
|
||||
var brush3 = new SolidBrush(Enabled ? SkinManager.ColorScheme.AccentColor : SkinManager.GetCheckBoxOffDisabledColor());
|
||||
var pen = new Pen(brush.Color);
|
||||
|
||||
// draw ripple animation
|
||||
if (Ripple && _rippleAnimationManager.IsAnimating())
|
||||
{
|
||||
for (var i = 0; i < _rippleAnimationManager.GetAnimationCount(); i++)
|
||||
{
|
||||
var animationValue = _rippleAnimationManager.GetProgress(i);
|
||||
var animationSource = new Point(CHECKBOX_CENTER, CHECKBOX_CENTER);
|
||||
var rippleBrush = new SolidBrush(Color.FromArgb((int)((animationValue * 40)), ((bool)_rippleAnimationManager.GetData(i)[0]) ? Color.Black : brush.Color));
|
||||
var rippleHeight = (Height % 2 == 0) ? Height - 3 : Height - 2;
|
||||
var rippleSize = (_rippleAnimationManager.GetDirection(i) == AnimationDirection.InOutIn) ? (int)(rippleHeight * (0.8d + (0.2d * animationValue))) : rippleHeight;
|
||||
using (var path = DrawHelper.CreateRoundRect(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize, rippleSize / 2))
|
||||
{
|
||||
g.FillPath(rippleBrush, path);
|
||||
}
|
||||
|
||||
rippleBrush.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
brush3.Dispose();
|
||||
|
||||
var checkMarkLineFill = new Rectangle(_boxOffset, _boxOffset, (int)((int)(FontHeight * 1.1) * animationProgress), (int)(FontHeight * 1.1));
|
||||
using (var checkmarkPath = DrawHelper.CreateRoundRect(_boxOffset, _boxOffset, (int)(FontHeight*1.1), (int)(FontHeight * 1.1), 1f))
|
||||
{
|
||||
var brush2 = new SolidBrush(DrawHelper.BlendColor(Parent.BackColor, Enabled ? SkinManager.GetCheckboxOffColor() : SkinManager.GetCheckBoxOffDisabledColor(), backgroundAlpha));
|
||||
var pen2 = new Pen(brush2.Color);
|
||||
g.FillPath(brush2, checkmarkPath);
|
||||
g.DrawPath(pen2, checkmarkPath);
|
||||
|
||||
g.FillRectangle(new SolidBrush(Parent.BackColor), _boxOffset + 2, _boxOffset + 2, (int)(FontHeight * 1.1) -4, (int)(FontHeight * 1.1) -4);
|
||||
g.DrawRectangle(new Pen(Parent.BackColor), _boxOffset + 2, _boxOffset + 2, (int)(FontHeight * 1.1) -4, (int)(FontHeight * 1.1) - 4);
|
||||
|
||||
brush2.Dispose();
|
||||
pen2.Dispose();
|
||||
|
||||
if (Enabled)
|
||||
{
|
||||
g.FillPath(brush, checkmarkPath);
|
||||
g.DrawPath(pen, checkmarkPath);
|
||||
}
|
||||
else if (Checked)
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
g.FillRectangle(brush, _boxOffset + 2, _boxOffset + 2, CHECKBOX_INNER_BOX_SIZE, CHECKBOX_INNER_BOX_SIZE);
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
}
|
||||
|
||||
g.DrawImageUnscaledAndClipped(DrawCheckMarkBitmap(), checkMarkLineFill);
|
||||
}
|
||||
|
||||
// draw checkbox text
|
||||
SizeF stringSize = g.MeasureString(Text, Font);
|
||||
g.DrawString(
|
||||
Text,
|
||||
Font,
|
||||
Enabled ? SkinManager.GetPrimaryTextBrush() : SkinManager.GetDisabledOrHintBrush(),
|
||||
_boxOffset + TEXT_OFFSET, Height / 2 - stringSize.Height / 2);
|
||||
|
||||
// dispose used paint objects
|
||||
pen.Dispose();
|
||||
brush.Dispose();
|
||||
}
|
||||
|
||||
private Bitmap DrawCheckMarkBitmap()
|
||||
{
|
||||
var checkMark = new Bitmap(CHECKBOX_SIZE, CHECKBOX_SIZE);
|
||||
var g = Graphics.FromImage(checkMark);
|
||||
|
||||
// clear everything, transparent
|
||||
g.Clear(Color.Transparent);
|
||||
|
||||
// draw the checkmark lines
|
||||
using (var pen = new Pen(Parent.BackColor, 2))
|
||||
{
|
||||
g.DrawLines(pen, CheckmarkLine);
|
||||
}
|
||||
|
||||
return checkMark;
|
||||
}
|
||||
|
||||
public override bool AutoSize
|
||||
{
|
||||
get { return base.AutoSize; }
|
||||
set
|
||||
{
|
||||
base.AutoSize = value;
|
||||
if (value)
|
||||
{
|
||||
Size = new Size(10, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsMouseInCheckArea()
|
||||
{
|
||||
return _boxRectangle.Contains(MouseLocation);
|
||||
}
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
Font = SkinManager.ROBOTO_MEDIUM_10;
|
||||
|
||||
if (DesignMode) return;
|
||||
|
||||
MouseState = MouseState.OUT;
|
||||
MouseEnter += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
};
|
||||
MouseLeave += (sender, args) =>
|
||||
{
|
||||
MouseLocation = new Point(-1, -1);
|
||||
MouseState = MouseState.OUT;
|
||||
};
|
||||
MouseDown += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.DOWN;
|
||||
|
||||
if (Ripple && args.Button == MouseButtons.Left && IsMouseInCheckArea())
|
||||
{
|
||||
_rippleAnimationManager.SecondaryIncrement = 0;
|
||||
_rippleAnimationManager.StartNewAnimation(AnimationDirection.InOutIn, new object[] { Checked });
|
||||
}
|
||||
};
|
||||
MouseUp += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
_rippleAnimationManager.SecondaryIncrement = 0.08;
|
||||
};
|
||||
MouseMove += (sender, args) =>
|
||||
{
|
||||
MouseLocation = args.Location;
|
||||
Cursor = IsMouseInCheckArea() ? Cursors.Hand : Cursors.Default;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
44
framework/MaterialSkin.Core/Controls/MaterialComboBox.cs
Normal file
44
framework/MaterialSkin.Core/Controls/MaterialComboBox.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public partial class MaterialComboBox : ComboBox
|
||||
{
|
||||
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
public MaterialComboBox()
|
||||
{
|
||||
|
||||
DrawMode = DrawMode.OwnerDrawFixed;
|
||||
|
||||
DrawItem += AdvancedComboBox_DrawItem;
|
||||
|
||||
}
|
||||
|
||||
void AdvancedComboBox_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
if (e.Index < 0)
|
||||
return;
|
||||
|
||||
ComboBox combo = sender as ComboBox;
|
||||
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
|
||||
e.Graphics.FillRectangle(new SolidBrush(SkinManager.ColorScheme.AccentColor),
|
||||
e.Bounds);
|
||||
else
|
||||
e.Graphics.FillRectangle(new SolidBrush(combo.BackColor),
|
||||
e.Bounds);
|
||||
|
||||
e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font,
|
||||
SkinManager.GetRaisedButtonTextBrush((e.State & DrawItemState.Selected) == DrawItemState.Selected),
|
||||
new Point(e.Bounds.X, e.Bounds.Y));
|
||||
|
||||
e.DrawFocusRectangle();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
195
framework/MaterialSkin.Core/Controls/MaterialContextMenuStrip.cs
Normal file
195
framework/MaterialSkin.Core/Controls/MaterialContextMenuStrip.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialContextMenuStrip : ContextMenuStrip, IMaterialControl
|
||||
{
|
||||
//Properties for managing the material design properties
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
|
||||
internal AnimationManager AnimationManager;
|
||||
internal Point AnimationSource;
|
||||
|
||||
public delegate void ItemClickStart(object sender, ToolStripItemClickedEventArgs e);
|
||||
public event ItemClickStart OnItemClickStart;
|
||||
|
||||
public MaterialContextMenuStrip()
|
||||
{
|
||||
Renderer = new MaterialToolStripRender();
|
||||
|
||||
AnimationManager = new AnimationManager(false)
|
||||
{
|
||||
Increment = 0.07,
|
||||
AnimationType = AnimationType.Linear
|
||||
};
|
||||
AnimationManager.OnAnimationProgress += sender => Invalidate();
|
||||
AnimationManager.OnAnimationFinished += sender => OnItemClicked(_delayesArgs);
|
||||
|
||||
BackColor = SkinManager.GetApplicationBackgroundColor();
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs mea)
|
||||
{
|
||||
base.OnMouseUp(mea);
|
||||
|
||||
AnimationSource = mea.Location;
|
||||
}
|
||||
|
||||
private ToolStripItemClickedEventArgs _delayesArgs;
|
||||
protected override void OnItemClicked(ToolStripItemClickedEventArgs e)
|
||||
{
|
||||
if (e.ClickedItem != null && !(e.ClickedItem is ToolStripSeparator))
|
||||
{
|
||||
if (e == _delayesArgs)
|
||||
{
|
||||
//The event has been fired manualy because the args are the ones we saved for delay
|
||||
base.OnItemClicked(e);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Interrupt the default on click, saving the args for the delay which is needed to display the animaton
|
||||
_delayesArgs = e;
|
||||
|
||||
//Fire custom event to trigger actions directly but keep cms open
|
||||
OnItemClickStart?.Invoke(this, e);
|
||||
|
||||
//Start animation
|
||||
AnimationManager.StartNewAnimation(AnimationDirection.In);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MaterialToolStripMenuItem : ToolStripMenuItem
|
||||
{
|
||||
public MaterialToolStripMenuItem()
|
||||
{
|
||||
AutoSize = false;
|
||||
Size = new Size(120, 30);
|
||||
}
|
||||
|
||||
protected override ToolStripDropDown CreateDefaultDropDown()
|
||||
{
|
||||
var baseDropDown = base.CreateDefaultDropDown();
|
||||
if (DesignMode) return baseDropDown;
|
||||
|
||||
var defaultDropDown = new MaterialContextMenuStrip();
|
||||
defaultDropDown.Items.AddRange(baseDropDown.Items);
|
||||
|
||||
return defaultDropDown;
|
||||
}
|
||||
}
|
||||
|
||||
internal class MaterialToolStripRender : ToolStripProfessionalRenderer, IMaterialControl
|
||||
{
|
||||
//Properties for managing the material design properties
|
||||
public int Depth { get; set; }
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
|
||||
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
var itemRect = GetItemRect(e.Item);
|
||||
var textRect = new Rectangle(24, itemRect.Y, itemRect.Width - (24 + 16), itemRect.Height);
|
||||
g.DrawString(
|
||||
e.Text,
|
||||
SkinManager.ROBOTO_MEDIUM_10,
|
||||
e.Item.Enabled ? SkinManager.GetPrimaryTextBrush() : SkinManager.GetDisabledOrHintBrush(),
|
||||
textRect,
|
||||
new StringFormat { LineAlignment = StringAlignment.Center });
|
||||
}
|
||||
|
||||
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.Clear(SkinManager.GetApplicationBackgroundColor());
|
||||
|
||||
//Draw background
|
||||
var itemRect = GetItemRect(e.Item);
|
||||
g.FillRectangle(e.Item.Selected && e.Item.Enabled ? SkinManager.GetCmsSelectedItemBrush() : new SolidBrush(SkinManager.GetApplicationBackgroundColor()), itemRect);
|
||||
|
||||
//Ripple animation
|
||||
var toolStrip = e.ToolStrip as MaterialContextMenuStrip;
|
||||
if (toolStrip != null)
|
||||
{
|
||||
var animationManager = toolStrip.AnimationManager;
|
||||
var animationSource = toolStrip.AnimationSource;
|
||||
if (toolStrip.AnimationManager.IsAnimating() && e.Item.Bounds.Contains(animationSource))
|
||||
{
|
||||
for (int i = 0; i < animationManager.GetAnimationCount(); i++)
|
||||
{
|
||||
var animationValue = animationManager.GetProgress(i);
|
||||
var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), Color.Black));
|
||||
var rippleSize = (int)(animationValue * itemRect.Width * 2.5);
|
||||
g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, itemRect.Y - itemRect.Height, rippleSize, itemRect.Height * 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
|
||||
{
|
||||
//base.OnRenderImageMargin(e);
|
||||
}
|
||||
|
||||
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
|
||||
g.FillRectangle(new SolidBrush(SkinManager.GetApplicationBackgroundColor()), e.Item.Bounds);
|
||||
g.DrawLine(
|
||||
new Pen(SkinManager.GetDividersColor()),
|
||||
new Point(e.Item.Bounds.Left, e.Item.Bounds.Height / 2),
|
||||
new Point(e.Item.Bounds.Right, e.Item.Bounds.Height / 2));
|
||||
}
|
||||
|
||||
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
|
||||
g.DrawRectangle(
|
||||
new Pen(SkinManager.GetDividersColor()),
|
||||
new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width - 1, e.AffectedBounds.Height - 1));
|
||||
}
|
||||
|
||||
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
const int ARROW_SIZE = 4;
|
||||
|
||||
var arrowMiddle = new Point(e.ArrowRectangle.X + e.ArrowRectangle.Width / 2, e.ArrowRectangle.Y + e.ArrowRectangle.Height / 2);
|
||||
var arrowBrush = e.Item.Enabled ? SkinManager.GetPrimaryTextBrush() : SkinManager.GetDisabledOrHintBrush();
|
||||
using (var arrowPath = new GraphicsPath())
|
||||
{
|
||||
arrowPath.AddLines(
|
||||
new[] {
|
||||
new Point(arrowMiddle.X - ARROW_SIZE, arrowMiddle.Y - ARROW_SIZE),
|
||||
new Point(arrowMiddle.X, arrowMiddle.Y),
|
||||
new Point(arrowMiddle.X - ARROW_SIZE, arrowMiddle.Y + ARROW_SIZE) });
|
||||
arrowPath.CloseFigure();
|
||||
|
||||
g.FillPath(arrowBrush, arrowPath);
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle GetItemRect(ToolStripItem item)
|
||||
{
|
||||
return new Rectangle(0, item.ContentRectangle.Y, item.ContentRectangle.Width + 4, item.ContentRectangle.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
framework/MaterialSkin.Core/Controls/MaterialDivider.cs
Normal file
27
framework/MaterialSkin.Core/Controls/MaterialDivider.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public sealed class MaterialDivider : Control, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
public MaterialDivider()
|
||||
{
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||
{
|
||||
BackColor = SkinManager.ColorScheme.PrimaryColor;
|
||||
base.OnPaintBackground(pevent);
|
||||
}
|
||||
}
|
||||
}
|
||||
200
framework/MaterialSkin.Core/Controls/MaterialFlatButton.cs
Normal file
200
framework/MaterialSkin.Core/Controls/MaterialFlatButton.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialFlatButton : Button, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
public bool Primary { get; set; }
|
||||
|
||||
private readonly AnimationManager _animationManager;
|
||||
private readonly AnimationManager _hoverAnimationManager;
|
||||
|
||||
private SizeF _textSize;
|
||||
|
||||
private Image _icon;
|
||||
public Image Icon
|
||||
{
|
||||
get { return _icon; }
|
||||
set
|
||||
{
|
||||
_icon = value;
|
||||
if (AutoSize)
|
||||
Size = GetPreferredSize();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialFlatButton()
|
||||
{
|
||||
Primary = false;
|
||||
|
||||
_animationManager = new AnimationManager(false)
|
||||
{
|
||||
Increment = 0.03,
|
||||
AnimationType = AnimationType.EaseOut
|
||||
};
|
||||
_hoverAnimationManager = new AnimationManager
|
||||
{
|
||||
Increment = 0.07,
|
||||
AnimationType = AnimationType.Linear
|
||||
};
|
||||
|
||||
_hoverAnimationManager.OnAnimationProgress += sender => Invalidate();
|
||||
_animationManager.OnAnimationProgress += sender => Invalidate();
|
||||
|
||||
AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
|
||||
Margin = new Padding(4, 6, 4, 6);
|
||||
Padding = new Padding(0);
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get { return base.Text; }
|
||||
set
|
||||
{
|
||||
base.Text = value;
|
||||
_textSize = CreateGraphics().MeasureString(value.ToUpper(), SkinManager.ROBOTO_MEDIUM_10);
|
||||
if (AutoSize)
|
||||
Size = GetPreferredSize();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pevent)
|
||||
{
|
||||
var g = pevent.Graphics;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
g.Clear(Parent.BackColor);
|
||||
|
||||
//Hover
|
||||
Color c = SkinManager.GetFlatButtonHoverBackgroundColor();
|
||||
using (Brush b = new SolidBrush(Color.FromArgb((int)(_hoverAnimationManager.GetProgress() * c.A), c.RemoveAlpha())))
|
||||
g.FillRectangle(b, ClientRectangle);
|
||||
|
||||
//Ripple
|
||||
if (_animationManager.IsAnimating())
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
for (var i = 0; i < _animationManager.GetAnimationCount(); i++)
|
||||
{
|
||||
var animationValue = _animationManager.GetProgress(i);
|
||||
var animationSource = _animationManager.GetSource(i);
|
||||
|
||||
using (Brush rippleBrush = new SolidBrush(Color.FromArgb((int)(101 - (animationValue * 100)), Color.Black)))
|
||||
{
|
||||
var rippleSize = (int)(animationValue * Width * 2);
|
||||
g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
|
||||
}
|
||||
}
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
}
|
||||
|
||||
//Icon
|
||||
var iconRect = new Rectangle(8, 6, 24, 24);
|
||||
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
// Center Icon
|
||||
iconRect.X += 2;
|
||||
|
||||
if (Icon != null)
|
||||
g.DrawImage(Icon, iconRect);
|
||||
|
||||
//Text
|
||||
var textRect = ClientRectangle;
|
||||
|
||||
if (Icon != null)
|
||||
{
|
||||
//
|
||||
// Resize and move Text container
|
||||
//
|
||||
|
||||
// First 8: left padding
|
||||
// 24: icon width
|
||||
// Second 4: space between Icon and Text
|
||||
// Third 8: right padding
|
||||
textRect.Width -= 8 + 24 + 4 + 8;
|
||||
|
||||
// First 8: left padding
|
||||
// 24: icon width
|
||||
// Second 4: space between Icon and Text
|
||||
textRect.X += 8 + 24 + 4;
|
||||
}
|
||||
|
||||
g.DrawString(
|
||||
Text.ToUpper(),
|
||||
SkinManager.ROBOTO_MEDIUM_10,
|
||||
Enabled ? (Primary ? SkinManager.ColorScheme.PrimaryBrush : SkinManager.GetPrimaryTextBrush()) : SkinManager.GetFlatButtonDisabledTextBrush(),
|
||||
textRect,
|
||||
new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }
|
||||
);
|
||||
}
|
||||
|
||||
private Size GetPreferredSize()
|
||||
{
|
||||
return GetPreferredSize(new Size(0, 0));
|
||||
}
|
||||
|
||||
public override Size GetPreferredSize(Size proposedSize)
|
||||
{
|
||||
// Provides extra space for proper padding for content
|
||||
var extra = 16;
|
||||
|
||||
if (Icon != null)
|
||||
// 24 is for icon size
|
||||
// 4 is for the space between icon & text
|
||||
extra += 24 + 4;
|
||||
|
||||
return new Size((int)Math.Ceiling(_textSize.Width) + extra, 36);
|
||||
}
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
if (DesignMode) return;
|
||||
|
||||
MouseState = MouseState.OUT;
|
||||
MouseEnter += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
_hoverAnimationManager.StartNewAnimation(AnimationDirection.In);
|
||||
Invalidate();
|
||||
};
|
||||
MouseLeave += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.OUT;
|
||||
_hoverAnimationManager.StartNewAnimation(AnimationDirection.Out);
|
||||
Invalidate();
|
||||
};
|
||||
MouseDown += (sender, args) =>
|
||||
{
|
||||
if (args.Button == MouseButtons.Left)
|
||||
{
|
||||
MouseState = MouseState.DOWN;
|
||||
|
||||
_animationManager.StartNewAnimation(AnimationDirection.In, args.Location);
|
||||
Invalidate();
|
||||
}
|
||||
};
|
||||
MouseUp += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
|
||||
Invalidate();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
619
framework/MaterialSkin.Core/Controls/MaterialForm.cs
Normal file
619
framework/MaterialSkin.Core/Controls/MaterialForm.cs
Normal file
@@ -0,0 +1,619 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialForm : Form, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
public new FormBorderStyle FormBorderStyle { get { return base.FormBorderStyle; } set { base.FormBorderStyle = value; } }
|
||||
public bool Sizable { get; set; }
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ReleaseCapture();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int TrackPopupMenuEx(IntPtr hmenu, uint fuFlags, int x, int y, IntPtr hwnd, IntPtr lptpm);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||||
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out] MONITORINFOEX info);
|
||||
|
||||
public const int WM_NCLBUTTONDOWN = 0xA1;
|
||||
public const int HT_CAPTION = 0x2;
|
||||
public const int WM_MOUSEMOVE = 0x0200;
|
||||
public const int WM_LBUTTONDOWN = 0x0201;
|
||||
public const int WM_LBUTTONUP = 0x0202;
|
||||
public const int WM_LBUTTONDBLCLK = 0x0203;
|
||||
public const int WM_RBUTTONDOWN = 0x0204;
|
||||
private const int HTBOTTOMLEFT = 16;
|
||||
private const int HTBOTTOMRIGHT = 17;
|
||||
private const int HTLEFT = 10;
|
||||
private const int HTRIGHT = 11;
|
||||
private const int HTBOTTOM = 15;
|
||||
private const int HTTOP = 12;
|
||||
private const int HTTOPLEFT = 13;
|
||||
private const int HTTOPRIGHT = 14;
|
||||
private const int BORDER_WIDTH = 7;
|
||||
private ResizeDirection _resizeDir;
|
||||
private ButtonState _buttonState = ButtonState.None;
|
||||
|
||||
private const int WMSZ_TOP = 3;
|
||||
private const int WMSZ_TOPLEFT = 4;
|
||||
private const int WMSZ_TOPRIGHT = 5;
|
||||
private const int WMSZ_LEFT = 1;
|
||||
private const int WMSZ_RIGHT = 2;
|
||||
private const int WMSZ_BOTTOM = 6;
|
||||
private const int WMSZ_BOTTOMLEFT = 7;
|
||||
private const int WMSZ_BOTTOMRIGHT = 8;
|
||||
|
||||
private readonly Dictionary<int, int> _resizingLocationsToCmd = new Dictionary<int, int>
|
||||
{
|
||||
{HTTOP, WMSZ_TOP},
|
||||
{HTTOPLEFT, WMSZ_TOPLEFT},
|
||||
{HTTOPRIGHT, WMSZ_TOPRIGHT},
|
||||
{HTLEFT, WMSZ_LEFT},
|
||||
{HTRIGHT, WMSZ_RIGHT},
|
||||
{HTBOTTOM, WMSZ_BOTTOM},
|
||||
{HTBOTTOMLEFT, WMSZ_BOTTOMLEFT},
|
||||
{HTBOTTOMRIGHT, WMSZ_BOTTOMRIGHT}
|
||||
};
|
||||
|
||||
private const int STATUS_BAR_BUTTON_WIDTH = STATUS_BAR_HEIGHT;
|
||||
private const int STATUS_BAR_HEIGHT = 24;
|
||||
private const int ACTION_BAR_HEIGHT = 40;
|
||||
|
||||
private const uint TPM_LEFTALIGN = 0x0000;
|
||||
private const uint TPM_RETURNCMD = 0x0100;
|
||||
|
||||
private const int WM_SYSCOMMAND = 0x0112;
|
||||
private const int WS_MINIMIZEBOX = 0x20000;
|
||||
private const int WS_SYSMENU = 0x00080000;
|
||||
|
||||
private const int MONITOR_DEFAULTTONEAREST = 2;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
|
||||
public class MONITORINFOEX
|
||||
{
|
||||
public int cbSize = Marshal.SizeOf(typeof(MONITORINFOEX));
|
||||
public RECT rcMonitor = new RECT();
|
||||
public RECT rcWork = new RECT();
|
||||
public int dwFlags = 0;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public char[] szDevice = new char[32];
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
|
||||
public int Width()
|
||||
{
|
||||
return right - left;
|
||||
}
|
||||
|
||||
public int Height()
|
||||
{
|
||||
return bottom - top;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ResizeDirection
|
||||
{
|
||||
BottomLeft,
|
||||
Left,
|
||||
Right,
|
||||
BottomRight,
|
||||
Bottom,
|
||||
None
|
||||
}
|
||||
|
||||
private enum ButtonState
|
||||
{
|
||||
XOver,
|
||||
MaxOver,
|
||||
MinOver,
|
||||
XDown,
|
||||
MaxDown,
|
||||
MinDown,
|
||||
None
|
||||
}
|
||||
|
||||
private readonly Cursor[] _resizeCursors = { Cursors.SizeNESW, Cursors.SizeWE, Cursors.SizeNWSE, Cursors.SizeWE, Cursors.SizeNS };
|
||||
|
||||
private Rectangle _minButtonBounds;
|
||||
private Rectangle _maxButtonBounds;
|
||||
private Rectangle _xButtonBounds;
|
||||
private Rectangle _actionBarBounds;
|
||||
private Rectangle _statusBarBounds;
|
||||
|
||||
private bool _maximized;
|
||||
private Size _previousSize;
|
||||
private Point _previousLocation;
|
||||
private bool _headerMouseDown;
|
||||
private MouseMessageFilter _mouseMessageFilter;
|
||||
|
||||
|
||||
public MaterialForm()
|
||||
{
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
DoubleBuffered = true;
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
|
||||
|
||||
// This enables the form to trigger the MouseMove event even when mouse is over another control
|
||||
//_mouseMessageFilter = new MouseMessageFilter();
|
||||
//Application.AddMessageFilter(_mouseMessageFilter);
|
||||
//MouseMessageFilter.MouseMove += OnGlobalMouseMove;
|
||||
}
|
||||
|
||||
public void RemoveMessageFilter()
|
||||
{
|
||||
Application.RemoveMessageFilter(_mouseMessageFilter);
|
||||
MouseMessageFilter.MouseMove -= OnGlobalMouseMove;
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
if (DesignMode || IsDisposed) return;
|
||||
|
||||
if (m.Msg == WM_LBUTTONDBLCLK)
|
||||
{
|
||||
MaximizeWindow(!_maximized);
|
||||
}
|
||||
else if (m.Msg == WM_MOUSEMOVE && _maximized &&
|
||||
(_statusBarBounds.Contains(PointToClient(Cursor.Position)) || _actionBarBounds.Contains(PointToClient(Cursor.Position))) &&
|
||||
!(_minButtonBounds.Contains(PointToClient(Cursor.Position)) || _maxButtonBounds.Contains(PointToClient(Cursor.Position)) || _xButtonBounds.Contains(PointToClient(Cursor.Position))))
|
||||
{
|
||||
if (_headerMouseDown)
|
||||
{
|
||||
_maximized = false;
|
||||
_headerMouseDown = false;
|
||||
|
||||
var mousePoint = PointToClient(Cursor.Position);
|
||||
if (mousePoint.X < Width / 2)
|
||||
Location = mousePoint.X < _previousSize.Width / 2 ?
|
||||
new Point(Cursor.Position.X - mousePoint.X, Cursor.Position.Y - mousePoint.Y) :
|
||||
new Point(Cursor.Position.X - _previousSize.Width / 2, Cursor.Position.Y - mousePoint.Y);
|
||||
else
|
||||
Location = Width - mousePoint.X < _previousSize.Width / 2 ?
|
||||
new Point(Cursor.Position.X - _previousSize.Width + Width - mousePoint.X, Cursor.Position.Y - mousePoint.Y) :
|
||||
new Point(Cursor.Position.X - _previousSize.Width / 2, Cursor.Position.Y - mousePoint.Y);
|
||||
|
||||
Size = _previousSize;
|
||||
ReleaseCapture();
|
||||
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
|
||||
}
|
||||
}
|
||||
else if (m.Msg == WM_LBUTTONDOWN &&
|
||||
(_statusBarBounds.Contains(PointToClient(Cursor.Position)) || _actionBarBounds.Contains(PointToClient(Cursor.Position))) &&
|
||||
!(_minButtonBounds.Contains(PointToClient(Cursor.Position)) || _maxButtonBounds.Contains(PointToClient(Cursor.Position)) || _xButtonBounds.Contains(PointToClient(Cursor.Position))))
|
||||
{
|
||||
if (!_maximized)
|
||||
{
|
||||
ReleaseCapture();
|
||||
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_headerMouseDown = true;
|
||||
}
|
||||
}
|
||||
else if (m.Msg == WM_RBUTTONDOWN)
|
||||
{
|
||||
Point cursorPos = PointToClient(Cursor.Position);
|
||||
|
||||
if (_statusBarBounds.Contains(cursorPos) && !_minButtonBounds.Contains(cursorPos) &&
|
||||
!_maxButtonBounds.Contains(cursorPos) && !_xButtonBounds.Contains(cursorPos))
|
||||
{
|
||||
// Show default system menu when right clicking titlebar
|
||||
var id = TrackPopupMenuEx(GetSystemMenu(Handle, false), TPM_LEFTALIGN | TPM_RETURNCMD, Cursor.Position.X, Cursor.Position.Y, Handle, IntPtr.Zero);
|
||||
|
||||
// Pass the command as a WM_SYSCOMMAND message
|
||||
SendMessage(Handle, WM_SYSCOMMAND, id, 0);
|
||||
}
|
||||
}
|
||||
else if (m.Msg == WM_NCLBUTTONDOWN)
|
||||
{
|
||||
// This re-enables resizing by letting the application know when the
|
||||
// user is trying to resize a side. This is disabled by default when using WS_SYSMENU.
|
||||
if (!Sizable) return;
|
||||
|
||||
byte bFlag = 0;
|
||||
|
||||
// Get which side to resize from
|
||||
if (_resizingLocationsToCmd.ContainsKey((int)m.WParam))
|
||||
bFlag = (byte)_resizingLocationsToCmd[(int)m.WParam];
|
||||
|
||||
if (bFlag != 0)
|
||||
SendMessage(Handle, WM_SYSCOMMAND, 0xF000 | bFlag, (int)m.LParam);
|
||||
}
|
||||
else if (m.Msg == WM_LBUTTONUP)
|
||||
{
|
||||
_headerMouseDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DropShadow { get; set; } = true;
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
const int CS_DROPSHADOW = 0x20000;
|
||||
var par = base.CreateParams;
|
||||
// WS_SYSMENU: Trigger the creation of the system menu
|
||||
// WS_MINIMIZEBOX: Allow minimizing from taskbar
|
||||
par.Style = par.Style | WS_MINIMIZEBOX | WS_SYSMENU; // Turn on the WS_MINIMIZEBOX style flag
|
||||
if(DropShadow)
|
||||
par.ClassStyle |= CS_DROPSHADOW;
|
||||
return par;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
if (DesignMode) return;
|
||||
UpdateButtons(e);
|
||||
|
||||
if (e.Button == MouseButtons.Left && !_maximized)
|
||||
ResizeForm(_resizeDir);
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
if (DesignMode) return;
|
||||
_buttonState = ButtonState.None;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
if (DesignMode) return;
|
||||
|
||||
if (Sizable)
|
||||
{
|
||||
//True if the mouse is hovering over a child control
|
||||
var isChildUnderMouse = GetChildAtPoint(e.Location) != null;
|
||||
|
||||
if (e.Location.X < BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !_maximized)
|
||||
{
|
||||
_resizeDir = ResizeDirection.BottomLeft;
|
||||
Cursor = Cursors.SizeNESW;
|
||||
}
|
||||
else if (e.Location.X < BORDER_WIDTH && !isChildUnderMouse && !_maximized)
|
||||
{
|
||||
_resizeDir = ResizeDirection.Left;
|
||||
Cursor = Cursors.SizeWE;
|
||||
}
|
||||
else if (e.Location.X > Width - BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !_maximized)
|
||||
{
|
||||
_resizeDir = ResizeDirection.BottomRight;
|
||||
Cursor = Cursors.SizeNWSE;
|
||||
}
|
||||
else if (e.Location.X > Width - BORDER_WIDTH && !isChildUnderMouse && !_maximized)
|
||||
{
|
||||
_resizeDir = ResizeDirection.Right;
|
||||
Cursor = Cursors.SizeWE;
|
||||
}
|
||||
else if (e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !_maximized)
|
||||
{
|
||||
_resizeDir = ResizeDirection.Bottom;
|
||||
Cursor = Cursors.SizeNS;
|
||||
}
|
||||
else
|
||||
{
|
||||
_resizeDir = ResizeDirection.None;
|
||||
|
||||
//Only reset the cursor when needed, this prevents it from flickering when a child control changes the cursor to its own needs
|
||||
if (_resizeCursors.Contains(Cursor))
|
||||
{
|
||||
Cursor = Cursors.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateButtons(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void OnGlobalMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
|
||||
if (IsDisposed) return;
|
||||
// Convert to client position and pass to Form.MouseMove
|
||||
var clientCursorPos = PointToClient(e.Location);
|
||||
var newE = new MouseEventArgs(MouseButtons.None, 0, clientCursorPos.X, clientCursorPos.Y, 0);
|
||||
OnMouseMove(newE);
|
||||
|
||||
}
|
||||
|
||||
private void UpdateButtons(MouseEventArgs e, bool up = false)
|
||||
{
|
||||
if (DesignMode) return;
|
||||
var oldState = _buttonState;
|
||||
bool showMin = MinimizeBox && ControlBox;
|
||||
bool showMax = MaximizeBox && ControlBox;
|
||||
|
||||
if (e.Button == MouseButtons.Left && !up)
|
||||
{
|
||||
if (showMin && !showMax && _maxButtonBounds.Contains(e.Location))
|
||||
_buttonState = ButtonState.MinDown;
|
||||
else if (showMin && showMax && _minButtonBounds.Contains(e.Location))
|
||||
_buttonState = ButtonState.MinDown;
|
||||
else if (showMax && _maxButtonBounds.Contains(e.Location))
|
||||
_buttonState = ButtonState.MaxDown;
|
||||
else if (ControlBox && _xButtonBounds.Contains(e.Location))
|
||||
_buttonState = ButtonState.XDown;
|
||||
else
|
||||
_buttonState = ButtonState.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (showMin && !showMax && _maxButtonBounds.Contains(e.Location))
|
||||
{
|
||||
_buttonState = ButtonState.MinOver;
|
||||
|
||||
if (oldState == ButtonState.MinDown && up)
|
||||
WindowState = FormWindowState.Minimized;
|
||||
}
|
||||
else if (showMin && showMax && _minButtonBounds.Contains(e.Location))
|
||||
{
|
||||
_buttonState = ButtonState.MinOver;
|
||||
|
||||
if (oldState == ButtonState.MinDown && up)
|
||||
WindowState = FormWindowState.Minimized;
|
||||
}
|
||||
else if (MaximizeBox && ControlBox && _maxButtonBounds.Contains(e.Location))
|
||||
{
|
||||
_buttonState = ButtonState.MaxOver;
|
||||
|
||||
if (oldState == ButtonState.MaxDown && up)
|
||||
MaximizeWindow(!_maximized);
|
||||
|
||||
}
|
||||
else if (ControlBox && _xButtonBounds.Contains(e.Location))
|
||||
{
|
||||
_buttonState = ButtonState.XOver;
|
||||
|
||||
if (oldState == ButtonState.XDown && up)
|
||||
Close();
|
||||
}
|
||||
else _buttonState = ButtonState.None;
|
||||
}
|
||||
|
||||
if (oldState != _buttonState) Invalidate();
|
||||
}
|
||||
|
||||
public void MaximizeWindow(bool maximize)
|
||||
{
|
||||
if (!MaximizeBox || !ControlBox) return;
|
||||
|
||||
_maximized = maximize;
|
||||
|
||||
if (maximize)
|
||||
{
|
||||
var monitorHandle = MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST);
|
||||
var monitorInfo = new MONITORINFOEX();
|
||||
GetMonitorInfo(new HandleRef(null, monitorHandle), monitorInfo);
|
||||
_previousSize = Size;
|
||||
_previousLocation = Location;
|
||||
|
||||
//var area=Screen.FromHandle(this.Handle).WorkingArea;
|
||||
|
||||
Size = new Size(monitorInfo.rcWork.Width(), monitorInfo.rcWork.Height());
|
||||
Location = new Point(monitorInfo.rcWork.left, monitorInfo.rcWork.top);
|
||||
//Size = new Size(area.Width, area.Height);
|
||||
//Location = new Point(area.Left, area.Top);
|
||||
}
|
||||
else
|
||||
{
|
||||
Size = _previousSize;
|
||||
Location = _previousLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
if (DesignMode) return;
|
||||
UpdateButtons(e, true);
|
||||
|
||||
base.OnMouseUp(e);
|
||||
ReleaseCapture();
|
||||
}
|
||||
|
||||
private void ResizeForm(ResizeDirection direction)
|
||||
{
|
||||
if (DesignMode) return;
|
||||
var dir = -1;
|
||||
switch (direction)
|
||||
{
|
||||
case ResizeDirection.BottomLeft:
|
||||
dir = HTBOTTOMLEFT;
|
||||
break;
|
||||
case ResizeDirection.Left:
|
||||
dir = HTLEFT;
|
||||
break;
|
||||
case ResizeDirection.Right:
|
||||
dir = HTRIGHT;
|
||||
break;
|
||||
case ResizeDirection.BottomRight:
|
||||
dir = HTBOTTOMRIGHT;
|
||||
break;
|
||||
case ResizeDirection.Bottom:
|
||||
dir = HTBOTTOM;
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseCapture();
|
||||
if (dir != -1)
|
||||
{
|
||||
SendMessage(Handle, WM_NCLBUTTONDOWN, dir, 0);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
|
||||
_minButtonBounds = new Rectangle((Width - SkinManager.FORM_PADDING / 2) - 3 * STATUS_BAR_BUTTON_WIDTH, 0, STATUS_BAR_BUTTON_WIDTH, STATUS_BAR_HEIGHT);
|
||||
_maxButtonBounds = new Rectangle((Width - SkinManager.FORM_PADDING / 2) - 2 * STATUS_BAR_BUTTON_WIDTH, 0, STATUS_BAR_BUTTON_WIDTH, STATUS_BAR_HEIGHT);
|
||||
_xButtonBounds = new Rectangle((Width - SkinManager.FORM_PADDING / 2) - STATUS_BAR_BUTTON_WIDTH, 0, STATUS_BAR_BUTTON_WIDTH, STATUS_BAR_HEIGHT);
|
||||
_statusBarBounds = new Rectangle(0, 0, Width, STATUS_BAR_HEIGHT);
|
||||
_actionBarBounds = new Rectangle(0, STATUS_BAR_HEIGHT, Width, ACTION_BAR_HEIGHT);
|
||||
}
|
||||
|
||||
public bool ShowSubHeader { get; set; }
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
g.Clear(SkinManager.GetApplicationBackgroundColor());
|
||||
g.FillRectangle(SkinManager.ColorScheme.DarkPrimaryBrush, _statusBarBounds);
|
||||
if(ShowSubHeader) g.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, _actionBarBounds);
|
||||
|
||||
//Draw border
|
||||
using (var borderPen = new Pen(SkinManager.GetDividersColor(), 1))
|
||||
{
|
||||
g.DrawLine(borderPen, new Point(0, _statusBarBounds.Bottom), new Point(0, Height - 2));
|
||||
g.DrawLine(borderPen, new Point(Width - 1, _statusBarBounds.Bottom), new Point(Width - 1, Height - 2));
|
||||
g.DrawLine(borderPen, new Point(0, Height - 1), new Point(Width - 1, Height - 1));
|
||||
}
|
||||
|
||||
// Determine whether or not we even should be drawing the buttons.
|
||||
bool showMin = MinimizeBox && ControlBox;
|
||||
bool showMax = MaximizeBox && ControlBox;
|
||||
var hoverBrush = SkinManager.GetFlatButtonHoverBackgroundBrush();
|
||||
var downBrush = SkinManager.GetFlatButtonPressedBackgroundBrush();
|
||||
|
||||
// When MaximizeButton == false, the minimize button will be painted in its place
|
||||
if (_buttonState == ButtonState.MinOver && showMin)
|
||||
g.FillRectangle(hoverBrush, showMax ? _minButtonBounds : _maxButtonBounds);
|
||||
|
||||
if (_buttonState == ButtonState.MinDown && showMin)
|
||||
g.FillRectangle(downBrush, showMax ? _minButtonBounds : _maxButtonBounds);
|
||||
|
||||
if (_buttonState == ButtonState.MaxOver && showMax)
|
||||
g.FillRectangle(hoverBrush, _maxButtonBounds);
|
||||
|
||||
if (_buttonState == ButtonState.MaxDown && showMax)
|
||||
g.FillRectangle(downBrush, _maxButtonBounds);
|
||||
|
||||
if (_buttonState == ButtonState.XOver && ControlBox)
|
||||
g.FillRectangle(hoverBrush, _xButtonBounds);
|
||||
|
||||
if (_buttonState == ButtonState.XDown && ControlBox)
|
||||
g.FillRectangle(downBrush, _xButtonBounds);
|
||||
|
||||
using (var formButtonsPen = new Pen(SkinManager.ACTION_BAR_TEXT_SECONDARY, 2))
|
||||
{
|
||||
// Minimize button.
|
||||
if (showMin)
|
||||
{
|
||||
int x = showMax ? _minButtonBounds.X : _maxButtonBounds.X;
|
||||
int y = showMax ? _minButtonBounds.Y : _maxButtonBounds.Y;
|
||||
|
||||
g.DrawLine(
|
||||
formButtonsPen,
|
||||
x + (int)(_minButtonBounds.Width * 0.33),
|
||||
y + (int)(_minButtonBounds.Height * 0.66),
|
||||
x + (int)(_minButtonBounds.Width * 0.66),
|
||||
y + (int)(_minButtonBounds.Height * 0.66)
|
||||
);
|
||||
}
|
||||
|
||||
// Maximize button
|
||||
if (showMax)
|
||||
{
|
||||
g.DrawRectangle(
|
||||
formButtonsPen,
|
||||
_maxButtonBounds.X + (int)(_maxButtonBounds.Width * 0.33),
|
||||
_maxButtonBounds.Y + (int)(_maxButtonBounds.Height * 0.36),
|
||||
(int)(_maxButtonBounds.Width * 0.39),
|
||||
(int)(_maxButtonBounds.Height * 0.31)
|
||||
);
|
||||
}
|
||||
|
||||
// Close button
|
||||
if (ControlBox)
|
||||
{
|
||||
g.DrawLine(
|
||||
formButtonsPen,
|
||||
_xButtonBounds.X + (int)(_xButtonBounds.Width * 0.33),
|
||||
_xButtonBounds.Y + (int)(_xButtonBounds.Height * 0.33),
|
||||
_xButtonBounds.X + (int)(_xButtonBounds.Width * 0.66),
|
||||
_xButtonBounds.Y + (int)(_xButtonBounds.Height * 0.66)
|
||||
);
|
||||
|
||||
g.DrawLine(
|
||||
formButtonsPen,
|
||||
_xButtonBounds.X + (int)(_xButtonBounds.Width * 0.66),
|
||||
_xButtonBounds.Y + (int)(_xButtonBounds.Height * 0.33),
|
||||
_xButtonBounds.X + (int)(_xButtonBounds.Width * 0.33),
|
||||
_xButtonBounds.Y + (int)(_xButtonBounds.Height * 0.66));
|
||||
}
|
||||
}
|
||||
|
||||
//Form title
|
||||
g.DrawString(Text, SkinManager.ROBOTO_MEDIUM_12, SkinManager.ColorScheme.TextBrush, new Rectangle(SkinManager.FORM_PADDING, STATUS_BAR_HEIGHT, Width-20, ACTION_BAR_HEIGHT), new StringFormat { LineAlignment = StringAlignment.Center,Alignment = StringAlignment.Near });
|
||||
//Primary title
|
||||
g.DrawString(PrimaryText, new Font("Roboto",20,FontStyle.Bold),SkinManager.ColorScheme.TextBrush, new Rectangle(SkinManager.FORM_PADDING, STATUS_BAR_HEIGHT, Width, ACTION_BAR_HEIGHT), new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center });
|
||||
g.DrawString(HeaderText, new Font("Roboto", 12, FontStyle.Bold), SkinManager.ColorScheme.TextBrush, new Rectangle(SkinManager.FORM_PADDING, 0, Width, STATUS_BAR_HEIGHT), new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Near });
|
||||
}
|
||||
public string PrimaryText { get; set; }
|
||||
public string HeaderText { get; set; }
|
||||
public Font TitleFont { get; set; }
|
||||
}
|
||||
|
||||
public class MouseMessageFilter : IMessageFilter
|
||||
{
|
||||
private const int WM_MOUSEMOVE = 0x0200;
|
||||
|
||||
public static event MouseEventHandler MouseMove;
|
||||
|
||||
public bool PreFilterMessage(ref Message m)
|
||||
{
|
||||
|
||||
if (m.Msg == WM_MOUSEMOVE)
|
||||
{
|
||||
if (MouseMove != null)
|
||||
{
|
||||
int x = Control.MousePosition.X, y = Control.MousePosition.Y;
|
||||
|
||||
MouseMove(null, new MouseEventArgs(MouseButtons.None, 0, x, y, 0));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
framework/MaterialSkin.Core/Controls/MaterialForm.resx
Normal file
120
framework/MaterialSkin.Core/Controls/MaterialForm.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
171
framework/MaterialSkin.Core/Controls/MaterialIcon.cs
Normal file
171
framework/MaterialSkin.Core/Controls/MaterialIcon.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
44
framework/MaterialSkin.Core/Controls/MaterialIndicator.Designer.cs
generated
Normal file
44
framework/MaterialSkin.Core/Controls/MaterialIndicator.Designer.cs
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
partial class MaterialIndicator
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// MaterialIndicator
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Name = "MaterialIndicator";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
51
framework/MaterialSkin.Core/Controls/MaterialIndicator.cs
Normal file
51
framework/MaterialSkin.Core/Controls/MaterialIndicator.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public partial class MaterialIndicator : UserControl
|
||||
{
|
||||
private bool _checked;
|
||||
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
|
||||
public Color CheckedColor { get; set; }
|
||||
public Color UncheckedColor { get; set; }
|
||||
public Color BorderColor { get; set; }
|
||||
public MaterialIndicator()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public bool Checked
|
||||
{
|
||||
get { return _checked; }
|
||||
set
|
||||
{
|
||||
_checked = value;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaintBackground(e);
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.FillEllipse(new SolidBrush(Checked?CheckedColor:UncheckedColor),1,1,Width-2,Height-2);
|
||||
e.Graphics.DrawEllipse(new Pen(BorderColor),1,1,Width-2,Height-2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
120
framework/MaterialSkin.Core/Controls/MaterialIndicator.resx
Normal file
120
framework/MaterialSkin.Core/Controls/MaterialIndicator.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
115
framework/MaterialSkin.Core/Controls/MaterialInputBox.Designer.cs
generated
Normal file
115
framework/MaterialSkin.Core/Controls/MaterialInputBox.Designer.cs
generated
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
namespace MaterialSkin.Core.Controls
|
||||
{
|
||||
partial class MaterialInputBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.materialRaisedButton1 = new MaterialSkin.Controls.MaterialRaisedButton();
|
||||
this.materialRaisedButton2 = new MaterialSkin.Controls.MaterialRaisedButton();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// materialRaisedButton1
|
||||
//
|
||||
this.materialRaisedButton1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.materialRaisedButton1.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.materialRaisedButton1.Depth = 0;
|
||||
this.materialRaisedButton1.DrawBorder = false;
|
||||
this.materialRaisedButton1.Icon = null;
|
||||
this.materialRaisedButton1.Location = new System.Drawing.Point(440, 88);
|
||||
this.materialRaisedButton1.MouseState = MaterialSkin.MouseState.HOVER;
|
||||
this.materialRaisedButton1.Name = "materialRaisedButton1";
|
||||
this.materialRaisedButton1.Primary = true;
|
||||
this.materialRaisedButton1.Size = new System.Drawing.Size(128, 48);
|
||||
this.materialRaisedButton1.TabIndex = 0;
|
||||
this.materialRaisedButton1.Text = "OK";
|
||||
this.materialRaisedButton1.UseVisualStyleBackColor = true;
|
||||
this.materialRaisedButton1.Click += new System.EventHandler(this.materialRaisedButton1_Click);
|
||||
//
|
||||
// materialRaisedButton2
|
||||
//
|
||||
this.materialRaisedButton2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.materialRaisedButton2.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.materialRaisedButton2.Depth = 0;
|
||||
this.materialRaisedButton2.DrawBorder = true;
|
||||
this.materialRaisedButton2.Icon = null;
|
||||
this.materialRaisedButton2.Location = new System.Drawing.Point(304, 88);
|
||||
this.materialRaisedButton2.MouseState = MaterialSkin.MouseState.HOVER;
|
||||
this.materialRaisedButton2.Name = "materialRaisedButton2";
|
||||
this.materialRaisedButton2.Primary = false;
|
||||
this.materialRaisedButton2.Size = new System.Drawing.Size(128, 48);
|
||||
this.materialRaisedButton2.TabIndex = 1;
|
||||
this.materialRaisedButton2.Text = "Cancel";
|
||||
this.materialRaisedButton2.UseVisualStyleBackColor = true;
|
||||
this.materialRaisedButton2.Click += new System.EventHandler(this.materialRaisedButton2_Click);
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.Location = new System.Drawing.Point(16, 56);
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(552, 23);
|
||||
this.textBox1.TabIndex = 0;
|
||||
this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.BackColor = System.Drawing.Color.White;
|
||||
this.label1.Location = new System.Drawing.Point(16, 32);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(38, 15);
|
||||
this.label1.TabIndex = 3;
|
||||
this.label1.Text = "label1";
|
||||
//
|
||||
// MaterialInputBox
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(579, 149);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.materialRaisedButton2);
|
||||
this.Controls.Add(this.materialRaisedButton1);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "MaterialInputBox";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private MaterialSkin.Controls.MaterialRaisedButton materialRaisedButton1;
|
||||
private MaterialSkin.Controls.MaterialRaisedButton materialRaisedButton2;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
||||
48
framework/MaterialSkin.Core/Controls/MaterialInputBox.cs
Normal file
48
framework/MaterialSkin.Core/Controls/MaterialInputBox.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Controls;
|
||||
|
||||
namespace MaterialSkin.Core.Controls
|
||||
{
|
||||
public partial class MaterialInputBox : MaterialForm
|
||||
{
|
||||
private MaterialInputBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
public static DialogResult Prompt(string title, string defaultValue, out string result, bool masked = false)
|
||||
{
|
||||
MaterialInputBox box = new MaterialInputBox {label1 = {Text = title}, textBox1 = {Text = defaultValue}};
|
||||
if (masked) box.textBox1.PasswordChar = '*';
|
||||
var res= box.ShowDialog();
|
||||
result = box.textBox1.Text;
|
||||
return res;
|
||||
}
|
||||
|
||||
private void textBox1_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Return)
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
}
|
||||
|
||||
private void materialRaisedButton2_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
|
||||
private void materialRaisedButton1_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
60
framework/MaterialSkin.Core/Controls/MaterialInputBox.resx
Normal file
60
framework/MaterialSkin.Core/Controls/MaterialInputBox.resx
Normal file
@@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
24
framework/MaterialSkin.Core/Controls/MaterialLabel.cs
Normal file
24
framework/MaterialSkin.Core/Controls/MaterialLabel.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialLabel : Label, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
|
||||
ForeColor = SkinManager.GetPrimaryTextColor();
|
||||
Font = SkinManager.ROBOTO_REGULAR_11;
|
||||
|
||||
BackColorChanged += (sender, args) => ForeColor = SkinManager.GetPrimaryTextColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
163
framework/MaterialSkin.Core/Controls/MaterialListView.cs
Normal file
163
framework/MaterialSkin.Core/Controls/MaterialListView.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialListView : ListView, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
[Browsable(false)]
|
||||
public Point MouseLocation { get; set; }
|
||||
[Browsable(false)]
|
||||
private ListViewItem HoveredItem { get; set; }
|
||||
|
||||
public MaterialListView()
|
||||
{
|
||||
GridLines = false;
|
||||
FullRowSelect = true;
|
||||
HeaderStyle = ColumnHeaderStyle.Nonclickable;
|
||||
View = View.Details;
|
||||
OwnerDraw = true;
|
||||
ResizeRedraw = true;
|
||||
BorderStyle = BorderStyle.None;
|
||||
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
|
||||
|
||||
//Fix for hovers, by default it doesn't redraw
|
||||
//TODO: should only redraw when the hovered line changed, this to reduce unnecessary redraws
|
||||
MouseLocation = new Point(-1, -1);
|
||||
MouseState = MouseState.OUT;
|
||||
MouseEnter += delegate
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
};
|
||||
MouseLeave += delegate
|
||||
{
|
||||
MouseState = MouseState.OUT;
|
||||
MouseLocation = new Point(-1, -1);
|
||||
HoveredItem = null;
|
||||
Invalidate();
|
||||
};
|
||||
MouseDown += delegate { MouseState = MouseState.DOWN; };
|
||||
MouseUp += delegate { MouseState = MouseState.HOVER; };
|
||||
MouseMove += delegate (object sender, MouseEventArgs args)
|
||||
{
|
||||
MouseLocation = args.Location;
|
||||
var currentHoveredItem = this.GetItemAt(MouseLocation.X, MouseLocation.Y);
|
||||
if (HoveredItem != currentHoveredItem)
|
||||
{
|
||||
HoveredItem = currentHoveredItem;
|
||||
Invalidate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
|
||||
{
|
||||
e.Graphics.FillRectangle(new SolidBrush(SkinManager.GetApplicationBackgroundColor()), new Rectangle(e.Bounds.X, e.Bounds.Y, Width, e.Bounds.Height));
|
||||
e.Graphics.DrawString(e.Header.Text,
|
||||
SkinManager.ROBOTO_MEDIUM_10,
|
||||
SkinManager.GetSecondaryTextBrush(),
|
||||
new Rectangle(e.Bounds.X + ITEM_PADDING, e.Bounds.Y + ITEM_PADDING, e.Bounds.Width - ITEM_PADDING * 2, e.Bounds.Height - ITEM_PADDING * 2),
|
||||
getStringFormat());
|
||||
}
|
||||
|
||||
private const int ITEM_PADDING = 12;
|
||||
protected override void OnDrawItem(DrawListViewItemEventArgs e)
|
||||
{
|
||||
//We draw the current line of items (= item with subitems) on a temp bitmap, then draw the bitmap at once. This is to reduce flickering.
|
||||
var b = new Bitmap(e.Item.Bounds.Width, e.Item.Bounds.Height);
|
||||
var g = Graphics.FromImage(b);
|
||||
|
||||
//always draw default background
|
||||
g.FillRectangle(new SolidBrush(SkinManager.GetApplicationBackgroundColor()), new Rectangle(new Point(e.Bounds.X, 0), e.Bounds.Size));
|
||||
|
||||
if (e.State.HasFlag(ListViewItemStates.Selected))
|
||||
{
|
||||
//selected background
|
||||
g.FillRectangle(SkinManager.GetFlatButtonPressedBackgroundBrush(), new Rectangle(new Point(e.Bounds.X, 0), e.Bounds.Size));
|
||||
}
|
||||
else if (e.Bounds.Contains(MouseLocation) && MouseState == MouseState.HOVER)
|
||||
{
|
||||
//hover background
|
||||
g.FillRectangle(SkinManager.GetFlatButtonHoverBackgroundBrush(), new Rectangle(new Point(e.Bounds.X, 0), e.Bounds.Size));
|
||||
}
|
||||
|
||||
|
||||
//Draw separator
|
||||
g.DrawLine(new Pen(SkinManager.GetDividersColor()), e.Bounds.Left, 0, e.Bounds.Right, 0);
|
||||
|
||||
foreach (ListViewItem.ListViewSubItem subItem in e.Item.SubItems)
|
||||
{
|
||||
//Draw text
|
||||
g.DrawString(subItem.Text, SkinManager.ROBOTO_MEDIUM_10, SkinManager.GetPrimaryTextBrush(),
|
||||
new Rectangle(subItem.Bounds.X + ITEM_PADDING, ITEM_PADDING, subItem.Bounds.Width - 2 * ITEM_PADDING, subItem.Bounds.Height - 2 * ITEM_PADDING),
|
||||
getStringFormat());
|
||||
}
|
||||
|
||||
e.Graphics.DrawImage((Image)b.Clone(), new Point(0, e.Item.Bounds.Location.Y));
|
||||
g.Dispose();
|
||||
b.Dispose();
|
||||
}
|
||||
|
||||
private StringFormat getStringFormat()
|
||||
{
|
||||
return new StringFormat
|
||||
{
|
||||
FormatFlags = StringFormatFlags.LineLimit,
|
||||
Trimming = StringTrimming.EllipsisCharacter,
|
||||
Alignment = StringAlignment.Near,
|
||||
LineAlignment = StringAlignment.Center
|
||||
};
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public class LogFont
|
||||
{
|
||||
public int lfHeight = 0;
|
||||
public int lfWidth = 0;
|
||||
public int lfEscapement = 0;
|
||||
public int lfOrientation = 0;
|
||||
public int lfWeight = 0;
|
||||
public byte lfItalic = 0;
|
||||
public byte lfUnderline = 0;
|
||||
public byte lfStrikeOut = 0;
|
||||
public byte lfCharSet = 0;
|
||||
public byte lfOutPrecision = 0;
|
||||
public byte lfClipPrecision = 0;
|
||||
public byte lfQuality = 0;
|
||||
public byte lfPitchAndFamily = 0;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string lfFaceName = string.Empty;
|
||||
}
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
|
||||
// This hack tries to apply the Roboto (24) font to all ListViewItems in this ListView
|
||||
// It only succeeds if the font is installed on the system.
|
||||
// Otherwise, a default sans serif font is used.
|
||||
var roboto24 = new Font(SkinManager.ROBOTO_MEDIUM_12.FontFamily, 24);
|
||||
var roboto24Logfont = new LogFont();
|
||||
roboto24.ToLogFont(roboto24Logfont);
|
||||
|
||||
try
|
||||
{
|
||||
// Font.FromLogFont is the method used when drawing ListViewItems. I 'test' it in this safer context to avoid unhandled exceptions later.
|
||||
Font = Font.FromLogFont(roboto24Logfont);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Font = new Font(FontFamily.GenericSansSerif, 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
framework/MaterialSkin.Core/Controls/MaterialLoader.Designer.cs
generated
Normal file
47
framework/MaterialSkin.Core/Controls/MaterialLoader.Designer.cs
generated
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
partial class MaterialLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// MaterialLoader
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(422, 189);
|
||||
ControlBox = false;
|
||||
Name = "MaterialLoader";
|
||||
StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
139
framework/MaterialSkin.Core/Controls/MaterialLoader.cs
Normal file
139
framework/MaterialSkin.Core/Controls/MaterialLoader.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public partial class MaterialLoader : MaterialForm
|
||||
{
|
||||
private static MaterialLoader _instance;
|
||||
private static Thread _loaderThread;
|
||||
private static ManualResetEvent _instanceReadyEvent = new ManualResetEvent(false);
|
||||
private readonly Dictionary<string, (MaterialProgressBar ProgressBar, Label Label)> _loadingProcesses;
|
||||
|
||||
private MaterialLoader()
|
||||
{
|
||||
InitializeComponent();
|
||||
RemoveMessageFilter();
|
||||
_loadingProcesses = new Dictionary<string, (MaterialProgressBar, Label)>();
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.StartPosition = FormStartPosition.CenterScreen;
|
||||
}
|
||||
|
||||
public static MaterialLoader Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null || _instance.IsDisposed)
|
||||
{
|
||||
_instanceReadyEvent.Reset();
|
||||
_loaderThread = new Thread(() =>
|
||||
{
|
||||
_instance = new MaterialLoader();
|
||||
_instance.Shown += (_, _) =>
|
||||
{
|
||||
_instanceReadyEvent.Set();
|
||||
};
|
||||
Application.Run(_instance);
|
||||
});
|
||||
_loaderThread.SetApartmentState(ApartmentState.STA);
|
||||
_loaderThread.Start();
|
||||
_instanceReadyEvent.WaitOne();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartLoading(string title)
|
||||
{
|
||||
if (_instance == null || !_instance.Visible)
|
||||
{
|
||||
Instance.Invoke(new Action(() =>
|
||||
{
|
||||
Instance.Show();
|
||||
Instance.Visible= true;
|
||||
}));
|
||||
}
|
||||
|
||||
Instance.Invoke(new Action(() =>
|
||||
{
|
||||
if (_loadingProcesses.ContainsKey(title))
|
||||
{
|
||||
return; // Prevent duplicate loading processes with the same title
|
||||
}
|
||||
|
||||
var progressBar = new MaterialProgressBar
|
||||
{
|
||||
Width = Instance.ClientSize.Width - 20,
|
||||
Height = 20,
|
||||
Top = 50 + (_loadingProcesses.Count * 30),
|
||||
Left = 10,
|
||||
Style = ProgressBarStyle.Marquee,
|
||||
MarqueeAnimationSpeed = 30,
|
||||
Value = 50,
|
||||
BackColor = Color.White
|
||||
};
|
||||
|
||||
var label = new Label
|
||||
{
|
||||
Text = title,
|
||||
AutoSize = true,
|
||||
Top = progressBar.Top - 20,
|
||||
Left = progressBar.Left,
|
||||
BackColor = Color.White
|
||||
};
|
||||
|
||||
_loadingProcesses[title] = (progressBar, label);
|
||||
Instance.Controls.Add(label);
|
||||
Instance.Controls.Add(progressBar);
|
||||
Instance.Height = 50 + (_loadingProcesses.Count * 30);
|
||||
Instance.Refresh();
|
||||
}));
|
||||
}
|
||||
|
||||
public void FinishLoading(string title)
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Instance.Invoke(new Action(() =>
|
||||
{
|
||||
if (_loadingProcesses.TryGetValue(title, out var components))
|
||||
{
|
||||
Instance.Controls.Remove(components.ProgressBar);
|
||||
Instance.Controls.Remove(components.Label);
|
||||
_loadingProcesses.Remove(title);
|
||||
RearrangeProgressBarsAndLabels();
|
||||
}
|
||||
|
||||
if (_loadingProcesses.Count == 0)
|
||||
{
|
||||
Instance.Visible= false;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void RearrangeProgressBarsAndLabels()
|
||||
{
|
||||
int index = 0;
|
||||
foreach (var components in _loadingProcesses.Values)
|
||||
{
|
||||
components.ProgressBar.Top = 50 + (index * 30);
|
||||
components.Label.Top = components.ProgressBar.Top - 20;
|
||||
index++;
|
||||
}
|
||||
|
||||
this.Height = 50 + (_loadingProcesses.Count * 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
120
framework/MaterialSkin.Core/Controls/MaterialLoader.resx
Normal file
120
framework/MaterialSkin.Core/Controls/MaterialLoader.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
90
framework/MaterialSkin.Core/Controls/MaterialMessageBox.Designer.cs
generated
Normal file
90
framework/MaterialSkin.Core/Controls/MaterialMessageBox.Designer.cs
generated
Normal file
@@ -0,0 +1,90 @@
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
partial class MaterialMessageBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.pnlButtons = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.lblTitle = new System.Windows.Forms.Label();
|
||||
this.lblText = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pnlButtons
|
||||
//
|
||||
this.pnlButtons.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.pnlButtons.AutoSize = true;
|
||||
this.pnlButtons.Location = new System.Drawing.Point(280, 204);
|
||||
this.pnlButtons.Name = "pnlButtons";
|
||||
this.pnlButtons.Padding = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.pnlButtons.Size = new System.Drawing.Size(140, 100);
|
||||
this.pnlButtons.TabIndex = 0;
|
||||
//
|
||||
// lblTitle
|
||||
//
|
||||
this.lblTitle.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblTitle.Location = new System.Drawing.Point(0, 20);
|
||||
this.lblTitle.Name = "lblTitle";
|
||||
this.lblTitle.Size = new System.Drawing.Size(1340, 40);
|
||||
this.lblTitle.TabIndex = 1;
|
||||
this.lblTitle.Text = "label1";
|
||||
this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// lblText
|
||||
//
|
||||
this.lblText.Location = new System.Drawing.Point(280, 80);
|
||||
this.lblText.Name = "lblText";
|
||||
this.lblText.Size = new System.Drawing.Size(680, 100);
|
||||
this.lblText.TabIndex = 2;
|
||||
this.lblText.Text = "label1";
|
||||
this.lblText.TextAlign = System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// MaterialMessageBox
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 26F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.ClientSize = new System.Drawing.Size(1338, 312);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.lblText);
|
||||
this.Controls.Add(this.lblTitle);
|
||||
this.Controls.Add(this.pnlButtons);
|
||||
this.Font = new System.Drawing.Font("Roboto", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||
this.Margin = new System.Windows.Forms.Padding(6);
|
||||
this.Name = "MaterialMessageBox";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.FlowLayoutPanel pnlButtons;
|
||||
private System.Windows.Forms.Label lblTitle;
|
||||
private System.Windows.Forms.Label lblText;
|
||||
}
|
||||
}
|
||||
86
framework/MaterialSkin.Core/Controls/MaterialMessageBox.cs
Normal file
86
framework/MaterialSkin.Core/Controls/MaterialMessageBox.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public partial class MaterialMessageBox : MaterialForm
|
||||
{
|
||||
[Browsable(false)]
|
||||
private MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
private MaterialMessageBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
BackColor = SkinManager.GetApplicationBackgroundColor();
|
||||
Left = 0;
|
||||
Width = Screen.PrimaryScreen.WorkingArea.Width;
|
||||
Top = (Screen.PrimaryScreen.WorkingArea.Height - Height) / 2;
|
||||
lblTitle.BackColor = SkinManager.ColorScheme.PrimaryColor;
|
||||
lblTitle.ForeColor= SkinManager.ColorScheme.TextColor;
|
||||
lblText.Left = (Width - lblText.Width) / 2;
|
||||
|
||||
}
|
||||
|
||||
private void AlignControls()
|
||||
{
|
||||
pnlButtons.Left = (Width - pnlButtons.Width) / 2;
|
||||
}
|
||||
|
||||
public static DialogResult Show(string text)
|
||||
{
|
||||
return Show(null, text, string.Empty, MessageBoxButtons.OK);
|
||||
}
|
||||
public static DialogResult Show(IWin32Window owner,string text, string caption, MessageBoxButtons buttons)
|
||||
{
|
||||
var mb = new MaterialMessageBox();
|
||||
mb.lblTitle.Text = caption;
|
||||
mb.lblText.Text = text;
|
||||
List<DialogResult> results;
|
||||
switch (buttons)
|
||||
{
|
||||
case MessageBoxButtons.OK:
|
||||
results=new List<DialogResult>(){DialogResult.OK};
|
||||
break;
|
||||
case MessageBoxButtons.OKCancel:
|
||||
results = new List<DialogResult>() { DialogResult.OK,DialogResult.Cancel };
|
||||
break;
|
||||
case MessageBoxButtons.AbortRetryIgnore:
|
||||
results = new List<DialogResult>() { DialogResult.Abort,DialogResult.Retry,DialogResult.Ignore };
|
||||
break;
|
||||
case MessageBoxButtons.YesNoCancel:
|
||||
results = new List<DialogResult>() { DialogResult.Yes,DialogResult.No,DialogResult.Cancel };
|
||||
break;
|
||||
case MessageBoxButtons.YesNo:
|
||||
results = new List<DialogResult>() { DialogResult.Yes,DialogResult.No };
|
||||
break;
|
||||
case MessageBoxButtons.RetryCancel:
|
||||
results = new List<DialogResult>() { DialogResult.Retry,DialogResult.Cancel };
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(buttons), buttons, null);
|
||||
}
|
||||
|
||||
var btns=Enum.GetNames(typeof(DialogResult));
|
||||
foreach (var btn in results)
|
||||
{
|
||||
MaterialRaisedButton opt = new MaterialRaisedButton();
|
||||
opt.Size = new Size(180, 60);
|
||||
opt.Margin = new Padding(10, 20, 10, 0);
|
||||
opt.Text = Enum.GetName(typeof(DialogResult),btn);
|
||||
opt.Click += (sender, args) =>
|
||||
mb.DialogResult = btn;
|
||||
mb.pnlButtons.Controls.Add(opt);
|
||||
mb.AlignControls();
|
||||
}
|
||||
|
||||
return mb.ShowDialog(owner);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
120
framework/MaterialSkin.Core/Controls/MaterialMessageBox.resx
Normal file
120
framework/MaterialSkin.Core/Controls/MaterialMessageBox.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
16
framework/MaterialSkin.Core/Controls/MaterialPanel.cs
Normal file
16
framework/MaterialSkin.Core/Controls/MaterialPanel.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialPanel:Panel
|
||||
{
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
|
||||
e.Graphics.Clear(SkinManager.GetApplicationBackgroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
134
framework/MaterialSkin.Core/Controls/MaterialProgressBar.cs
Normal file
134
framework/MaterialSkin.Core/Controls/MaterialProgressBar.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Material design-like progress bar
|
||||
/// </summary>
|
||||
public class MaterialProgressBar : ProgressBar, IMaterialControl
|
||||
{
|
||||
private int _animation;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MaterialProgressBar"/> class.
|
||||
/// </summary>
|
||||
public MaterialProgressBar()
|
||||
{
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
||||
Timer timer = new Timer();
|
||||
timer.Interval = 33;
|
||||
timer.Tick += Timer_Tick;
|
||||
timer.Enabled = true;
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the depth.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The depth.
|
||||
/// </value>
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the skin manager.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The skin manager.
|
||||
/// </value>
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the state of the mouse.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The state of the mouse.
|
||||
/// </value>
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs the work of setting the specified bounds of this control.
|
||||
/// </summary>
|
||||
/// <param name="x">The new <see cref="P:System.Windows.Forms.Control.Left" /> property value of the control.</param>
|
||||
/// <param name="y">The new <see cref="P:System.Windows.Forms.Control.Top" /> property value of the control.</param>
|
||||
/// <param name="width">The new <see cref="P:System.Windows.Forms.Control.Width" /> property value of the control.</param>
|
||||
/// <param name="height">The new <see cref="P:System.Windows.Forms.Control.Height" /> property value of the control.</param>
|
||||
/// <param name="specified">A bitwise combination of the <see cref="T:System.Windows.Forms.BoundsSpecified" /> values.</param>
|
||||
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
|
||||
{
|
||||
base.SetBoundsCore(x, y, width, 5, specified);
|
||||
}
|
||||
|
||||
protected override void CreateHandle()
|
||||
{
|
||||
base.CreateHandle();
|
||||
if (Style == ProgressBarStyle.Marquee)
|
||||
StartAnimation();
|
||||
}
|
||||
|
||||
private void StartAnimation()
|
||||
{
|
||||
_animation = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
|
||||
/// </summary>
|
||||
/// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
if (Style == ProgressBarStyle.Marquee)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
|
||||
var animationProgress = (int)(e.ClipRectangle.Width * ((double)_animation / Maximum));
|
||||
var doneProgress = (int)(e.ClipRectangle.Width * ((double)Value / Maximum));
|
||||
if (doneProgress + animationProgress > e.ClipRectangle.Width)
|
||||
doneProgress = e.ClipRectangle.Width - animationProgress;
|
||||
|
||||
_animation+=Step;
|
||||
if (_animation >= 100) _animation = -Value;
|
||||
e.Graphics.FillRectangle(SkinManager.GetDisabledOrHintBrush(), 0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
|
||||
e.Graphics.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, animationProgress, 0, doneProgress, e.ClipRectangle.Height);
|
||||
//Task.Delay(33).ContinueWith((x) =>
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// System.Action a = () => { };
|
||||
// if (InvokeRequired)
|
||||
// Invoke(a);
|
||||
// else
|
||||
// a();
|
||||
// }catch{}
|
||||
|
||||
//});
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var doneProgress = (int)(e.ClipRectangle.Width * ((double)Value / Maximum));
|
||||
e.Graphics.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, 0, 0, doneProgress, e.ClipRectangle.Height);
|
||||
e.Graphics.FillRectangle(SkinManager.GetDisabledOrHintBrush(), doneProgress, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
211
framework/MaterialSkin.Core/Controls/MaterialRadioButton.cs
Normal file
211
framework/MaterialSkin.Core/Controls/MaterialRadioButton.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialRadioButton : RadioButton, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
[Browsable(false)]
|
||||
public Point MouseLocation { get; set; }
|
||||
|
||||
private bool ripple;
|
||||
[Category("Behavior")]
|
||||
public bool Ripple
|
||||
{
|
||||
get { return ripple; }
|
||||
set
|
||||
{
|
||||
ripple = value;
|
||||
AutoSize = AutoSize; //Make AutoSize directly set the bounds.
|
||||
|
||||
if (value)
|
||||
{
|
||||
Margin = new Padding(0);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// animation managers
|
||||
private readonly AnimationManager _animationManager;
|
||||
private readonly AnimationManager _rippleAnimationManager;
|
||||
|
||||
// size related variables which should be recalculated onsizechanged
|
||||
private Rectangle _radioButtonBounds;
|
||||
private int _boxOffset;
|
||||
|
||||
// size constants
|
||||
private const int RADIOBUTTON_SIZE = 19;
|
||||
private const int RADIOBUTTON_SIZE_HALF = RADIOBUTTON_SIZE / 2;
|
||||
private const int RADIOBUTTON_OUTER_CIRCLE_WIDTH = 2;
|
||||
private const int RADIOBUTTON_INNER_CIRCLE_SIZE = RADIOBUTTON_SIZE - (2 * RADIOBUTTON_OUTER_CIRCLE_WIDTH);
|
||||
|
||||
public MaterialRadioButton()
|
||||
{
|
||||
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
|
||||
|
||||
_animationManager = new AnimationManager
|
||||
{
|
||||
AnimationType = AnimationType.EaseInOut,
|
||||
Increment = 0.06
|
||||
};
|
||||
_rippleAnimationManager = new AnimationManager(false)
|
||||
{
|
||||
AnimationType = AnimationType.Linear,
|
||||
Increment = 0.10,
|
||||
SecondaryIncrement = 0.08
|
||||
};
|
||||
_animationManager.OnAnimationProgress += sender => Invalidate();
|
||||
_rippleAnimationManager.OnAnimationProgress += sender => Invalidate();
|
||||
|
||||
CheckedChanged += (sender, args) => _animationManager.StartNewAnimation(Checked ? AnimationDirection.In : AnimationDirection.Out);
|
||||
|
||||
SizeChanged += OnSizeChanged;
|
||||
|
||||
Ripple = true;
|
||||
MouseLocation = new Point(-1, -1);
|
||||
}
|
||||
private void OnSizeChanged(object sender, EventArgs eventArgs)
|
||||
{
|
||||
_boxOffset = Height / 2 - (int)Math.Ceiling(RADIOBUTTON_SIZE / 2d);
|
||||
_radioButtonBounds = new Rectangle(_boxOffset, _boxOffset, RADIOBUTTON_SIZE, RADIOBUTTON_SIZE);
|
||||
}
|
||||
|
||||
public override Size GetPreferredSize(Size proposedSize)
|
||||
{
|
||||
var width = _boxOffset + 20 + (int)CreateGraphics().MeasureString(Text, SkinManager.ROBOTO_MEDIUM_10).Width;
|
||||
return Ripple ? new Size(width, 30) : new Size(width, 20);
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pevent)
|
||||
{
|
||||
var g = pevent.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
// clear the control
|
||||
g.Clear(Parent.BackColor);
|
||||
|
||||
var RADIOBUTTON_CENTER = _boxOffset + RADIOBUTTON_SIZE_HALF;
|
||||
|
||||
var animationProgress = _animationManager.GetProgress();
|
||||
|
||||
int colorAlpha = Enabled ? (int)(animationProgress * 255.0) : SkinManager.GetCheckBoxOffDisabledColor().A;
|
||||
int backgroundAlpha = Enabled ? (int)(SkinManager.GetCheckboxOffColor().A * (1.0 - animationProgress)) : SkinManager.GetCheckBoxOffDisabledColor().A;
|
||||
float animationSize = (float)(animationProgress * 8f);
|
||||
float animationSizeHalf = animationSize / 2;
|
||||
animationSize = (float)(animationProgress * 9f);
|
||||
|
||||
var brush = new SolidBrush(Color.FromArgb(colorAlpha, Enabled ? SkinManager.ColorScheme.AccentColor : SkinManager.GetCheckBoxOffDisabledColor()));
|
||||
var pen = new Pen(brush.Color);
|
||||
|
||||
// draw ripple animation
|
||||
if (Ripple && _rippleAnimationManager.IsAnimating())
|
||||
{
|
||||
for (var i = 0; i < _rippleAnimationManager.GetAnimationCount(); i++)
|
||||
{
|
||||
var animationValue = _rippleAnimationManager.GetProgress(i);
|
||||
var animationSource = new Point(RADIOBUTTON_CENTER, RADIOBUTTON_CENTER);
|
||||
var rippleBrush = new SolidBrush(Color.FromArgb((int)((animationValue * 40)), ((bool)_rippleAnimationManager.GetData(i)[0]) ? Color.Black : brush.Color));
|
||||
var rippleHeight = (Height % 2 == 0) ? Height - 3 : Height - 2;
|
||||
var rippleSize = (_rippleAnimationManager.GetDirection(i) == AnimationDirection.InOutIn) ? (int)(rippleHeight * (0.8d + (0.2d * animationValue))) : rippleHeight;
|
||||
using (var path = DrawHelper.CreateRoundRect(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize, rippleSize / 2))
|
||||
{
|
||||
g.FillPath(rippleBrush, path);
|
||||
}
|
||||
|
||||
rippleBrush.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// draw radiobutton circle
|
||||
Color uncheckedColor = DrawHelper.BlendColor(Parent.BackColor, Enabled ? SkinManager.GetCheckboxOffColor() : SkinManager.GetCheckBoxOffDisabledColor(), backgroundAlpha);
|
||||
|
||||
using (var path = DrawHelper.CreateRoundRect(_boxOffset, _boxOffset, RADIOBUTTON_SIZE, RADIOBUTTON_SIZE, 9f))
|
||||
{
|
||||
g.FillPath(new SolidBrush(uncheckedColor), path);
|
||||
|
||||
if (Enabled)
|
||||
{
|
||||
g.FillPath(brush, path);
|
||||
}
|
||||
}
|
||||
|
||||
g.FillEllipse(
|
||||
new SolidBrush(Parent.BackColor),
|
||||
RADIOBUTTON_OUTER_CIRCLE_WIDTH + _boxOffset,
|
||||
RADIOBUTTON_OUTER_CIRCLE_WIDTH + _boxOffset,
|
||||
RADIOBUTTON_INNER_CIRCLE_SIZE,
|
||||
RADIOBUTTON_INNER_CIRCLE_SIZE);
|
||||
|
||||
if (Checked)
|
||||
{
|
||||
using (var path = DrawHelper.CreateRoundRect(RADIOBUTTON_CENTER - animationSizeHalf, RADIOBUTTON_CENTER - animationSizeHalf, animationSize, animationSize, 4f))
|
||||
{
|
||||
g.FillPath(brush, path);
|
||||
}
|
||||
}
|
||||
SizeF stringSize = g.MeasureString(Text, SkinManager.ROBOTO_MEDIUM_10);
|
||||
g.DrawString(Text, SkinManager.ROBOTO_MEDIUM_10, Enabled ? SkinManager.GetPrimaryTextBrush() : SkinManager.GetDisabledOrHintBrush(), _boxOffset + 22, Height / 2 - stringSize.Height / 2);
|
||||
|
||||
brush.Dispose();
|
||||
pen.Dispose();
|
||||
}
|
||||
|
||||
private bool IsMouseInCheckArea()
|
||||
{
|
||||
return _radioButtonBounds.Contains(MouseLocation);
|
||||
}
|
||||
|
||||
protected override void OnCreateControl()
|
||||
{
|
||||
base.OnCreateControl();
|
||||
Font = SkinManager.ROBOTO_MEDIUM_10;
|
||||
|
||||
if (DesignMode) return;
|
||||
|
||||
MouseState = MouseState.OUT;
|
||||
MouseEnter += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
};
|
||||
MouseLeave += (sender, args) =>
|
||||
{
|
||||
MouseLocation = new Point(-1, -1);
|
||||
MouseState = MouseState.OUT;
|
||||
};
|
||||
MouseDown += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.DOWN;
|
||||
|
||||
if (Ripple && args.Button == MouseButtons.Left && IsMouseInCheckArea())
|
||||
{
|
||||
_rippleAnimationManager.SecondaryIncrement = 0;
|
||||
_rippleAnimationManager.StartNewAnimation(AnimationDirection.InOutIn, new object[] { Checked });
|
||||
}
|
||||
};
|
||||
MouseUp += (sender, args) =>
|
||||
{
|
||||
MouseState = MouseState.HOVER;
|
||||
_rippleAnimationManager.SecondaryIncrement = 0.08;
|
||||
};
|
||||
MouseMove += (sender, args) =>
|
||||
{
|
||||
MouseLocation = args.Location;
|
||||
Cursor = IsMouseInCheckArea() ? Cursors.Hand : Cursors.Default;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
216
framework/MaterialSkin.Core/Controls/MaterialRaisedButton.cs
Normal file
216
framework/MaterialSkin.Core/Controls/MaterialRaisedButton.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
using System;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialRaisedButton : Button, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
public bool Primary { get; set; }
|
||||
|
||||
|
||||
public bool DrawBorder
|
||||
{
|
||||
get { return _drawBorder; }
|
||||
set
|
||||
{
|
||||
_drawBorder = value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly AnimationManager _animationManager;
|
||||
|
||||
private SizeF _textSize;
|
||||
|
||||
private Image _icon;
|
||||
private bool _drawBorder;
|
||||
private Point _lastLocation;
|
||||
private bool _wasClick;
|
||||
|
||||
public Image Icon
|
||||
{
|
||||
get { return _icon; }
|
||||
set
|
||||
{
|
||||
_icon = value;
|
||||
if (AutoSize)
|
||||
Size = GetPreferredSize();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialRaisedButton()
|
||||
{
|
||||
Primary = true;
|
||||
Cursor = Cursors.Hand;
|
||||
_animationManager = new AnimationManager(false)
|
||||
{
|
||||
Increment = 0.02,
|
||||
AnimationType = AnimationType.EaseOut
|
||||
};
|
||||
_animationManager.OnAnimationProgress += sender => Invalidate();
|
||||
_animationManager.OnAnimationFinished +=AnimationManagerOnOnAnimationFinished;
|
||||
AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
|
||||
}
|
||||
|
||||
private void AnimationManagerOnOnAnimationFinished(object o)
|
||||
{
|
||||
if (_wasClick)
|
||||
{
|
||||
_wasClick = false;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override string Text
|
||||
{
|
||||
get { return base.Text; }
|
||||
set
|
||||
{
|
||||
base.Text = value;
|
||||
_textSize = CreateGraphics().MeasureString(value.ToUpper(), SkinManager.ROBOTO_MEDIUM_10);
|
||||
if (AutoSize)
|
||||
Size = GetPreferredSize();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs mevent)
|
||||
{
|
||||
base.OnMouseUp(mevent);
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs mevent)
|
||||
{
|
||||
base.OnMouseDown(mevent);
|
||||
_lastLocation = mevent.Location;
|
||||
|
||||
}
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
_animationManager.StartNewAnimation(AnimationDirection.In,_lastLocation);
|
||||
base.OnClick(e);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pevent)
|
||||
{
|
||||
try
|
||||
{
|
||||
var g = pevent.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
//g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
g.Clear(Parent.BackColor);
|
||||
|
||||
using (var backgroundPath = DrawHelper.CreateRoundRect(ClientRectangle.X,
|
||||
ClientRectangle.Y,
|
||||
ClientRectangle.Width - 1,
|
||||
ClientRectangle.Height - 1,
|
||||
1f))
|
||||
{
|
||||
|
||||
g.FillPath(
|
||||
Enabled
|
||||
? (Primary
|
||||
? SkinManager.ColorScheme.PrimaryBrush
|
||||
: SkinManager.GetRaisedButtonBackgroundBrush())
|
||||
: Brushes.DarkGray, backgroundPath);
|
||||
if (!Primary && this.DrawBorder)
|
||||
{
|
||||
g.DrawPath(SkinManager.ColorScheme.PrimaryPen, backgroundPath);
|
||||
}
|
||||
}
|
||||
|
||||
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 ? Color.White : SkinManager.ColorScheme.PrimaryColor));
|
||||
var rippleSize = (int) (animationValue * Width * 2);
|
||||
g.FillEllipse(rippleBrush,
|
||||
new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2,
|
||||
rippleSize, rippleSize));
|
||||
}
|
||||
}
|
||||
|
||||
//Icon
|
||||
var iconRect = new Rectangle(8, 6, 24, 24);
|
||||
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
// Center Icon
|
||||
iconRect.X += 2;
|
||||
|
||||
if (Icon != null)
|
||||
g.DrawImage(Icon, iconRect);
|
||||
|
||||
//Text
|
||||
var textRect = ClientRectangle;
|
||||
|
||||
if (Icon != null)
|
||||
{
|
||||
//
|
||||
// Resize and move Text container
|
||||
//
|
||||
|
||||
// First 8: left padding
|
||||
// 24: icon width
|
||||
// Second 4: space between Icon and Text
|
||||
// Third 8: right padding
|
||||
textRect.Width -= 8 + 24 + 4 + 8;
|
||||
|
||||
// First 8: left padding
|
||||
// 24: icon width
|
||||
// Second 4: space between Icon and Text
|
||||
textRect.X += 8 + 24 + 4;
|
||||
}
|
||||
|
||||
g.DrawString(
|
||||
Text.ToUpper(),
|
||||
Font,
|
||||
Primary ? SkinManager.GetRaisedButtonTextBrush(Primary) : SkinManager.ColorScheme.PrimaryBrush,
|
||||
textRect,
|
||||
new StringFormat {Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center});
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private Size GetPreferredSize()
|
||||
{
|
||||
return GetPreferredSize(new Size(0, 0));
|
||||
}
|
||||
|
||||
public override Size GetPreferredSize(Size proposedSize)
|
||||
{
|
||||
// Provides extra space for proper padding for content
|
||||
var extra = 16;
|
||||
|
||||
if (Icon != null)
|
||||
// 24 is for icon size
|
||||
// 4 is for the space between icon & text
|
||||
extra += 24 + 4;
|
||||
|
||||
return new Size((int)Math.Ceiling(_textSize.Width) + extra, 36);
|
||||
}
|
||||
}
|
||||
}
|
||||
1169
framework/MaterialSkin.Core/Controls/MaterialSingleLineTextField.cs
Normal file
1169
framework/MaterialSkin.Core/Controls/MaterialSingleLineTextField.cs
Normal file
File diff suppressed because it is too large
Load Diff
22
framework/MaterialSkin.Core/Controls/MaterialTabControl.cs
Normal file
22
framework/MaterialSkin.Core/Controls/MaterialTabControl.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialTabControl : TabControl, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
|
||||
else base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
}
|
||||
175
framework/MaterialSkin.Core/Controls/MaterialTabSelector.cs
Normal file
175
framework/MaterialSkin.Core/Controls/MaterialTabSelector.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Animations;
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public class MaterialTabSelector : Control, IMaterialControl
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int Depth { get; set; }
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
[Browsable(false)]
|
||||
public MouseState MouseState { get; set; }
|
||||
|
||||
private MaterialTabControl _baseTabControl;
|
||||
public MaterialTabControl BaseTabControl
|
||||
{
|
||||
get { return _baseTabControl; }
|
||||
set
|
||||
{
|
||||
_baseTabControl = value;
|
||||
if (_baseTabControl == null) return;
|
||||
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
|
||||
_baseTabControl.Deselected += (sender, args) =>
|
||||
{
|
||||
_previousSelectedTabIndex = _baseTabControl.SelectedIndex;
|
||||
};
|
||||
_baseTabControl.SelectedIndexChanged += (sender, args) =>
|
||||
{
|
||||
_animationManager.SetProgress(0);
|
||||
_animationManager.StartNewAnimation(AnimationDirection.In);
|
||||
};
|
||||
_baseTabControl.ControlAdded += delegate
|
||||
{
|
||||
Invalidate();
|
||||
};
|
||||
_baseTabControl.ControlRemoved += delegate
|
||||
{
|
||||
Invalidate();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private int _previousSelectedTabIndex;
|
||||
private Point _animationSource;
|
||||
private readonly AnimationManager _animationManager;
|
||||
|
||||
private List<Rectangle> _tabRects;
|
||||
private const int TAB_HEADER_PADDING = 24;
|
||||
private const int TAB_INDICATOR_HEIGHT = 2;
|
||||
|
||||
public MaterialTabSelector()
|
||||
{
|
||||
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer, true);
|
||||
Height = 48;
|
||||
|
||||
_animationManager = new AnimationManager
|
||||
{
|
||||
AnimationType = AnimationType.EaseOut,
|
||||
Increment = 0.04
|
||||
};
|
||||
_animationManager.OnAnimationProgress += sender => Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
var g = e.Graphics;
|
||||
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||
|
||||
g.Clear(SkinManager.ColorScheme.PrimaryColor);
|
||||
|
||||
if (_baseTabControl == null) return;
|
||||
|
||||
if (!_animationManager.IsAnimating() || _tabRects == null || _tabRects.Count != _baseTabControl.TabCount)
|
||||
UpdateTabRects();
|
||||
|
||||
var animationProgress = _animationManager.GetProgress();
|
||||
|
||||
//Click feedback
|
||||
if (_animationManager.IsAnimating())
|
||||
{
|
||||
var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationProgress * 50)), Color.White));
|
||||
var rippleSize = (int)(animationProgress * _tabRects[_baseTabControl.SelectedIndex].Width * 1.75);
|
||||
|
||||
g.SetClip(_tabRects[_baseTabControl.SelectedIndex]);
|
||||
g.FillEllipse(rippleBrush, new Rectangle(_animationSource.X - rippleSize / 2, _animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
|
||||
g.ResetClip();
|
||||
rippleBrush.Dispose();
|
||||
}
|
||||
|
||||
//Draw tab headers
|
||||
foreach (TabPage tabPage in _baseTabControl.TabPages)
|
||||
{
|
||||
var currentTabIndex = _baseTabControl.TabPages.IndexOf(tabPage);
|
||||
Brush textBrush = new SolidBrush(Color.FromArgb(CalculateTextAlpha(currentTabIndex, animationProgress), SkinManager.ColorScheme.TextColor));
|
||||
|
||||
g.DrawString(tabPage.Text.ToUpper(), SkinManager.ROBOTO_MEDIUM_10, textBrush, _tabRects[currentTabIndex], new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
|
||||
textBrush.Dispose();
|
||||
}
|
||||
|
||||
//Animate tab indicator
|
||||
var previousSelectedTabIndexIfHasOne = _previousSelectedTabIndex == -1 ? _baseTabControl.SelectedIndex : _previousSelectedTabIndex;
|
||||
var previousActiveTabRect = _tabRects[previousSelectedTabIndexIfHasOne];
|
||||
var activeTabPageRect = _tabRects[_baseTabControl.SelectedIndex];
|
||||
|
||||
var y = activeTabPageRect.Bottom - 2;
|
||||
var x = previousActiveTabRect.X + (int)((activeTabPageRect.X - previousActiveTabRect.X) * animationProgress);
|
||||
var width = previousActiveTabRect.Width + (int)((activeTabPageRect.Width - previousActiveTabRect.Width) * animationProgress);
|
||||
|
||||
g.FillRectangle(SkinManager.ColorScheme.AccentBrush, x, y, width, TAB_INDICATOR_HEIGHT);
|
||||
}
|
||||
|
||||
private int CalculateTextAlpha(int tabIndex, double animationProgress)
|
||||
{
|
||||
int primaryA = SkinManager.ACTION_BAR_TEXT.A;
|
||||
int secondaryA = SkinManager.ACTION_BAR_TEXT_SECONDARY.A;
|
||||
|
||||
if (tabIndex == _baseTabControl.SelectedIndex && !_animationManager.IsAnimating())
|
||||
{
|
||||
return primaryA;
|
||||
}
|
||||
if (tabIndex != _previousSelectedTabIndex && tabIndex != _baseTabControl.SelectedIndex)
|
||||
{
|
||||
return secondaryA;
|
||||
}
|
||||
if (tabIndex == _previousSelectedTabIndex)
|
||||
{
|
||||
return primaryA - (int)((primaryA - secondaryA) * animationProgress);
|
||||
}
|
||||
return secondaryA + (int)((primaryA - secondaryA) * animationProgress);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseUp(e);
|
||||
|
||||
if (_tabRects == null) UpdateTabRects();
|
||||
for (var i = 0; i < _tabRects.Count; i++)
|
||||
{
|
||||
if (_tabRects[i].Contains(e.Location))
|
||||
{
|
||||
_baseTabControl.SelectedIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
_animationSource = e.Location;
|
||||
}
|
||||
|
||||
private void UpdateTabRects()
|
||||
{
|
||||
_tabRects = new List<Rectangle>();
|
||||
|
||||
//If there isn't a base tab control, the rects shouldn't be calculated
|
||||
//If there aren't tab pages in the base tab control, the list should just be empty which has been set already; exit the void
|
||||
if (_baseTabControl == null || _baseTabControl.TabCount == 0) return;
|
||||
|
||||
//Calculate the bounds of each tab header specified in the base tab control
|
||||
using (var b = new Bitmap(1, 1))
|
||||
{
|
||||
using (var g = Graphics.FromImage(b))
|
||||
{
|
||||
_tabRects.Add(new Rectangle(SkinManager.FORM_PADDING, 0, TAB_HEADER_PADDING * 2 + (int)g.MeasureString(_baseTabControl.TabPages[0].Text, SkinManager.ROBOTO_MEDIUM_10).Width, Height));
|
||||
for (int i = 1; i < _baseTabControl.TabPages.Count; i++)
|
||||
{
|
||||
_tabRects.Add(new Rectangle(_tabRects[i - 1].Right, 0, TAB_HEADER_PADDING * 2 + (int)g.MeasureString(_baseTabControl.TabPages[i].Text, SkinManager.ROBOTO_MEDIUM_10).Width, Height));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
framework/MaterialSkin.Core/Controls/MaterialUpDown.Designer.cs
generated
Normal file
103
framework/MaterialSkin.Core/Controls/MaterialUpDown.Designer.cs
generated
Normal file
@@ -0,0 +1,103 @@
|
||||
using MaterialSkin.Core.Resources;
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
partial class MaterialUpDown
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.materialIcon2 = new MaterialSkin.Controls.MaterialIcon();
|
||||
this.materialIcon1 = new MaterialSkin.Controls.MaterialIcon();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.textBox1.Font = new System.Drawing.Font("Roboto", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||
this.textBox1.Location = new System.Drawing.Point(80, 20);
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(100, 28);
|
||||
this.textBox1.TabIndex = 13;
|
||||
this.textBox1.Text = "0000";
|
||||
this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.textBox1.Click += new System.EventHandler(this.textBox1_Click);
|
||||
this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
|
||||
this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
|
||||
this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
|
||||
this.textBox1.Leave += new System.EventHandler(this.textBox1_Leave);
|
||||
//
|
||||
// materialIcon2
|
||||
//
|
||||
this.materialIcon2.Clickable = true;
|
||||
this.materialIcon2.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.materialIcon2.Image = Resource1.rounded_add_button;
|
||||
this.materialIcon2.Location = new System.Drawing.Point(200, 0);
|
||||
this.materialIcon2.Name = "materialIcon2";
|
||||
this.materialIcon2.Primary = false;
|
||||
this.materialIcon2.Size = new System.Drawing.Size(64, 64);
|
||||
this.materialIcon2.TabIndex = 12;
|
||||
this.materialIcon2.Text = "materialIcon2";
|
||||
this.materialIcon2.Click += new System.EventHandler(this.materialIcon2_Click);
|
||||
this.materialIcon2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.materialIcon2_MouseDown);
|
||||
this.materialIcon2.MouseLeave += new System.EventHandler(this.materialIcon2_MouseLeave);
|
||||
this.materialIcon2.MouseUp += new System.Windows.Forms.MouseEventHandler(this.materialIcon2_MouseUp);
|
||||
//
|
||||
// materialIcon1
|
||||
//
|
||||
this.materialIcon1.Clickable = true;
|
||||
this.materialIcon1.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.materialIcon1.Image = Resource1.round_delete_button;
|
||||
this.materialIcon1.Location = new System.Drawing.Point(0, 0);
|
||||
this.materialIcon1.Name = "materialIcon1";
|
||||
this.materialIcon1.Primary = false;
|
||||
this.materialIcon1.Size = new System.Drawing.Size(64, 64);
|
||||
this.materialIcon1.TabIndex = 11;
|
||||
this.materialIcon1.Text = "materialIcon1";
|
||||
this.materialIcon1.Click += new System.EventHandler(this.materialIcon1_Click);
|
||||
this.materialIcon1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.materialIcon1_MouseDown);
|
||||
this.materialIcon1.MouseLeave += new System.EventHandler(this.materialIcon1_MouseLeave);
|
||||
this.materialIcon1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.materialIcon1_MouseUp);
|
||||
//
|
||||
// MaterialUpDown
|
||||
//
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.materialIcon2);
|
||||
this.Controls.Add(this.materialIcon1);
|
||||
this.Name = "MaterialUpDown";
|
||||
this.Size = new System.Drawing.Size(266, 66);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private MaterialIcon materialIcon2;
|
||||
private MaterialIcon materialIcon1;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
}
|
||||
}
|
||||
256
framework/MaterialSkin.Core/Controls/MaterialUpDown.cs
Normal file
256
framework/MaterialSkin.Core/Controls/MaterialUpDown.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace MaterialSkin.Controls
|
||||
{
|
||||
public partial class MaterialUpDown : UserControl,INotifyPropertyChanged
|
||||
{
|
||||
private double _value;
|
||||
private bool _mouseDown;
|
||||
private int _direction;
|
||||
|
||||
public MaterialUpDown()
|
||||
{
|
||||
InitializeComponent();
|
||||
textBox1.BackColor = SkinManager.GetApplicationBackgroundColor();
|
||||
|
||||
AllowDecimal = false;
|
||||
AllowKeyboard=true;
|
||||
}
|
||||
[Browsable(false)]
|
||||
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
|
||||
|
||||
public bool AllowDecimal { get; set; }
|
||||
|
||||
public bool AllowKeyboard
|
||||
{
|
||||
get { return _allowKeyboard; }
|
||||
set
|
||||
{
|
||||
_allowKeyboard = value;
|
||||
textBox1.ReadOnly = !_allowKeyboard || _readOnly;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideControls
|
||||
{
|
||||
get { return _hideControls; }
|
||||
set
|
||||
{
|
||||
_hideControls = value;
|
||||
materialIcon1.Visible = !value;
|
||||
materialIcon2.Visible = !value;
|
||||
}
|
||||
}
|
||||
|
||||
public double Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
if (_value>Max)
|
||||
{
|
||||
_value = Max;
|
||||
}
|
||||
|
||||
if (_value < Min)
|
||||
{
|
||||
_value = Min;
|
||||
}
|
||||
|
||||
if (!AllowDecimal)
|
||||
{
|
||||
_value = Math.Floor(_value);
|
||||
}
|
||||
|
||||
Action a = ()=> textBox1.Text = _value.ToString();
|
||||
if (textBox1.InvokeRequired)
|
||||
textBox1.Invoke(a);
|
||||
else
|
||||
a();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReadOnly
|
||||
{
|
||||
get { return _readOnly; }
|
||||
set
|
||||
{
|
||||
_readOnly = value;
|
||||
materialIcon1.Enabled = !value;
|
||||
materialIcon2.Enabled = !value;
|
||||
textBox1.ReadOnly = !_allowKeyboard || _readOnly;
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged= delegate { };
|
||||
|
||||
public double Max { get; set; }
|
||||
public double Min { get; set; }
|
||||
public double Step { get; set; }
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
e.Graphics.Clear(SkinManager.GetApplicationBackgroundColor());
|
||||
}
|
||||
|
||||
private void materialIcon2_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void materialIcon1_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private async void HoldCountDown(CancellationToken cancellationSourceToken)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
while (_mouseDown&&!cancellationSourceToken.IsCancellationRequested)
|
||||
{
|
||||
Value += Step*_direction;
|
||||
await Task.Delay(100/(int)Math.Max(1,Math.Min(5,(DateTime.Now-startTime).TotalSeconds)));
|
||||
}
|
||||
}
|
||||
|
||||
private CancellationTokenSource _cancellationSource;
|
||||
private bool _readOnly;
|
||||
private bool _allowKeyboard;
|
||||
|
||||
private void materialIcon2_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
|
||||
_cancellationSource =new CancellationTokenSource();
|
||||
Value += Step;
|
||||
|
||||
_mouseDown = true;
|
||||
_direction = 1;
|
||||
Task.Run(()=> HoldCountDown(_cancellationSource.Token));
|
||||
}
|
||||
|
||||
private void materialIcon2_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (_cancellationSource != null)
|
||||
{
|
||||
_cancellationSource.Cancel();
|
||||
_cancellationSource = null;
|
||||
}
|
||||
_mouseDown = false;
|
||||
PropertyChanged(this,new PropertyChangedEventArgs(nameof(Value)));
|
||||
}
|
||||
|
||||
private void materialIcon1_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_cancellationSource = new CancellationTokenSource();
|
||||
Value -= Step;
|
||||
|
||||
_mouseDown = true;
|
||||
_direction = -1;
|
||||
Task.Run(() => HoldCountDown(_cancellationSource.Token));
|
||||
}
|
||||
|
||||
private void materialIcon1_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (_cancellationSource != null)
|
||||
{
|
||||
_cancellationSource.Cancel();
|
||||
_cancellationSource = null;
|
||||
}
|
||||
_mouseDown = false;
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Value)));
|
||||
}
|
||||
|
||||
private void materialIcon2_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
materialIcon2_MouseUp(null,null);
|
||||
}
|
||||
|
||||
private void materialIcon1_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
materialIcon1_MouseUp(null, null);
|
||||
}
|
||||
|
||||
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
|
||||
|
||||
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
|
||||
(e.KeyChar != '.'))
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// only allow one decimal point
|
||||
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_validate = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource = null;
|
||||
private bool _validate;
|
||||
private bool _hideControls;
|
||||
|
||||
private void textBox1_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
if (textBox1.ReadOnly) return;
|
||||
textBox1.SelectAll();
|
||||
|
||||
}
|
||||
|
||||
private void textBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void textBox1_Leave(object sender, EventArgs e)
|
||||
{
|
||||
if (double.TryParse((sender as TextBox).Text, NumberStyles.AllowDecimalPoint, CultureInfo.GetCultureInfo("en-us"), out var value))
|
||||
{
|
||||
if (_cancellationTokenSource != null) _cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var newValue = value;
|
||||
var token = _cancellationTokenSource.Token;
|
||||
if (token.IsCancellationRequested) throw new OperationCanceledException();
|
||||
Value = newValue;
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Value)));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void textBox1_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
|
||||
textBox1_Leave(textBox1,null);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
framework/MaterialSkin.Core/Controls/MaterialUpDown.resx
Normal file
120
framework/MaterialSkin.Core/Controls/MaterialUpDown.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
43
framework/MaterialSkin.Core/DrawHelper.cs
Normal file
43
framework/MaterialSkin.Core/DrawHelper.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace MaterialSkin
|
||||
{
|
||||
static class DrawHelper
|
||||
{
|
||||
public static GraphicsPath CreateRoundRect(float x, float y, float width, float height, float radius)
|
||||
{
|
||||
var gp = new GraphicsPath();
|
||||
gp.AddLine(x + radius, y, x + width - (radius * 2), y);
|
||||
gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90);
|
||||
gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2));
|
||||
gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
|
||||
gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height);
|
||||
gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
|
||||
gp.AddLine(x, y + height - (radius * 2), x, y + radius);
|
||||
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90);
|
||||
gp.CloseFigure();
|
||||
return gp;
|
||||
}
|
||||
|
||||
public static GraphicsPath CreateRoundRect(Rectangle rect, float radius)
|
||||
{
|
||||
return CreateRoundRect(rect.X, rect.Y, rect.Width, rect.Height, radius);
|
||||
}
|
||||
|
||||
public static Color BlendColor(Color backgroundColor, Color frontColor, double blend)
|
||||
{
|
||||
var ratio = blend / 255d;
|
||||
var invRatio = 1d - ratio;
|
||||
var r = (int)((backgroundColor.R * invRatio) + (frontColor.R * ratio));
|
||||
var g = (int)((backgroundColor.G * invRatio) + (frontColor.G * ratio));
|
||||
var b = (int)((backgroundColor.B * invRatio) + (frontColor.B * ratio));
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
|
||||
public static Color BlendColor(Color backgroundColor, Color frontColor)
|
||||
{
|
||||
return BlendColor(backgroundColor, frontColor, frontColor.A);
|
||||
}
|
||||
}
|
||||
}
|
||||
279
framework/MaterialSkin.Core/Gesture/GestureEventArgs.cs
Normal file
279
framework/MaterialSkin.Core/Gesture/GestureEventArgs.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
#region The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Robert Prouse http://www.alteridem.net
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
// Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
#region Using Directives
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace MaterialSkin.Gesture
|
||||
{
|
||||
#region GestureEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all the gesture based events
|
||||
/// </summary>
|
||||
public abstract class GestureEventArgs : EventArgs
|
||||
{
|
||||
internal GestureEventArgs( GestureInfo info )
|
||||
{
|
||||
Location = new Point( info.location.x, info.location.y );
|
||||
Info = info;
|
||||
Handled = true;
|
||||
}
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
protected static int LoDWord( IntPtr lParam )
|
||||
{
|
||||
return LoDWord( lParam.ToInt64() );
|
||||
}
|
||||
|
||||
protected static int HiDWord( IntPtr lParam )
|
||||
{
|
||||
return HiDWord( lParam.ToInt64() );
|
||||
}
|
||||
|
||||
protected static int LoDWord( long l )
|
||||
{
|
||||
return (int)(l & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
protected static int HiDWord( long l )
|
||||
{
|
||||
return (int)((l >> 32) & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
protected static short LoWord( int i )
|
||||
{
|
||||
return (short)(i & 0xFFFF);
|
||||
}
|
||||
|
||||
protected static short HiWord( int i )
|
||||
{
|
||||
return (short)((i >> 16) & 0xFFFF);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
protected GestureInfo Info { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location of the gesture in Screen (not client) coordinates.
|
||||
/// </summary>
|
||||
public Point Location { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="GestureEventArgs"/> is beginning.
|
||||
/// </summary>
|
||||
public bool Begin
|
||||
{
|
||||
get { return Info.Begin; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="GestureEventArgs"/> is ending
|
||||
/// </summary>
|
||||
public bool End
|
||||
{
|
||||
get { return Info.End; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the window message was handled. Set this to false if you don't handle the message.
|
||||
/// </summary>
|
||||
public bool Handled { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PanEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Event for the Pan gesture
|
||||
/// </summary>
|
||||
public class PanEventArgs : GestureEventArgs
|
||||
{
|
||||
internal PanEventArgs( GestureInfo info, Point lastPanPoint )
|
||||
: base( info )
|
||||
{
|
||||
int hiword = HiDWord( info.arguments );
|
||||
InertiaVector = new Point( LoWord( hiword ), HiWord( hiword ) );
|
||||
PanOffset = new Point( Location.X - lastPanPoint.X, Location.Y - lastPanPoint.Y );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="GestureEventArgs"/> has triggered inertia.
|
||||
/// </summary>
|
||||
public bool Inertia
|
||||
{
|
||||
get { return Info.Inertia; }
|
||||
}
|
||||
|
||||
public Point InertiaVector { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pan offset since the last pan message.
|
||||
/// </summary>
|
||||
public Point PanOffset { get; private set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ZoomEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Event for the Zoom gesture
|
||||
/// </summary>
|
||||
public class ZoomEventArgs : GestureEventArgs
|
||||
{
|
||||
internal ZoomEventArgs( GestureInfo info, long lastZoomDistance )
|
||||
: base( info )
|
||||
{
|
||||
Distance = info.arguments;
|
||||
PercentChange = (double)Distance / lastZoomDistance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the distance between the two points as they are being zoomed.
|
||||
/// </summary>
|
||||
public long Distance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the percent changed since the last zoom message
|
||||
/// </summary>
|
||||
public double PercentChange { get; private set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PressAndTapEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Event for the Press and Tap gesture
|
||||
/// </summary>
|
||||
public class PressAndTapEventArgs : GestureEventArgs
|
||||
{
|
||||
internal PressAndTapEventArgs( GestureInfo info )
|
||||
: base( info )
|
||||
{
|
||||
int pointsStruct = LoDWord( info.arguments );
|
||||
Distance = new Point( LoWord( pointsStruct ), HiWord( pointsStruct ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the distance between the two points.
|
||||
/// </summary>
|
||||
public Point Distance { get; private set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RotateEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Event for the Rotate gesture
|
||||
/// </summary>
|
||||
public class RotateEventArgs : GestureEventArgs
|
||||
{
|
||||
internal RotateEventArgs( GestureInfo info, double lastRotation )
|
||||
: base( info )
|
||||
{
|
||||
int loword = LoDWord( info.arguments );
|
||||
TotalAngle = RotateAngleFromArgument( loword );
|
||||
Angle = TotalAngle - lastRotation;
|
||||
string msg = string.Format("Total:{0} Angle:{1} Last:{2}", TotalAngle, Angle, lastRotation );
|
||||
System.Diagnostics.Debug.WriteLine( msg );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture argument helper that converts an argument to a rotation angle.
|
||||
/// </summary>
|
||||
/// <param name="arg">The argument to convert. Should be an unsigned 16-bit value.</param>
|
||||
/// <returns></returns>
|
||||
private static double RotateAngleFromArgument( int arg )
|
||||
{
|
||||
return ((arg / 65535.0) * 4.0 * Math.PI) - 2.0 * Math.PI;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the angle of rotation in Radians since the beginning of the gesture
|
||||
/// </summary>
|
||||
public double TotalAngle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the angle of rotation in Degrees since the beginning of the gesture
|
||||
/// </summary>
|
||||
public double TotalDegrees
|
||||
{
|
||||
get { return RadiandsToDegrees( TotalAngle ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the angle of rotation in Radians since the last rotation message
|
||||
/// </summary>
|
||||
public double Angle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the angle of rotation in Degrees since the last rotation message
|
||||
/// </summary>
|
||||
public double Degrees
|
||||
{
|
||||
get { return RadiandsToDegrees( Angle ); }
|
||||
}
|
||||
|
||||
private double RadiandsToDegrees( double radians )
|
||||
{
|
||||
return radians * 180.0 / Math.PI;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TwoFingerTapEventArgs Class
|
||||
|
||||
/// <summary>
|
||||
/// Base class for the Two Finger Tap gesture
|
||||
/// </summary>
|
||||
public class TwoFingerTapEventArgs : GestureEventArgs
|
||||
{
|
||||
internal TwoFingerTapEventArgs( GestureInfo info )
|
||||
: base( info )
|
||||
{
|
||||
Distance = info.arguments;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the distance between the two points.
|
||||
/// </summary>
|
||||
public long Distance { get; private set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
446
framework/MaterialSkin.Core/Gesture/GestureListener.cs
Normal file
446
framework/MaterialSkin.Core/Gesture/GestureListener.cs
Normal file
@@ -0,0 +1,446 @@
|
||||
#region The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Robert Prouse http://www.alteridem.net
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
// Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
#region Using Directives
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace MaterialSkin.Gesture
|
||||
{
|
||||
[PermissionSet( SecurityAction.Demand, Name = "FullTrust" )]
|
||||
public sealed class GestureListener : NativeWindow
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
// Saved state
|
||||
private Point _lastPanPoint;
|
||||
private double _lastRotation;
|
||||
private long _lastZoom;
|
||||
|
||||
private readonly Control _parent;
|
||||
private readonly GestureConfig[] m_configs;
|
||||
private int _touchInputSize;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Events
|
||||
|
||||
public event EventHandler<PanEventArgs> Pan;
|
||||
public event EventHandler<PressAndTapEventArgs> PressAndTap;
|
||||
public event EventHandler<RotateEventArgs> Rotate;
|
||||
public event EventHandler<TwoFingerTapEventArgs> TwoFingerTap;
|
||||
public event EventHandler<ZoomEventArgs> Zoom;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GestureListener"/> class to receive all gestures.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
public GestureListener( Control parent )
|
||||
: this( parent, new[] { new GestureConfig( 0, GestureConfigurationFlag.GC_ALLGESTURES, 0 ) } )
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GestureListener"/> class to receive specific gestures.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="configs">The gesture configurations.</param>
|
||||
public GestureListener( Control parent, GestureConfig[] configs )
|
||||
{
|
||||
if ( parent.IsHandleCreated )
|
||||
{
|
||||
Initialize( parent );
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.HandleCreated += OnHandleCreated;
|
||||
}
|
||||
parent.HandleDestroyed += OnHandleDestroyed;
|
||||
|
||||
_parent = parent;
|
||||
m_configs = configs;
|
||||
_touchInputSize = Marshal.SizeOf(new TOUCHINPUT());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
[DllImport("user32")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool RegisterTouchWindow(System.IntPtr hWnd, ulong ulFlags);
|
||||
private void Initialize( Control parent )
|
||||
{
|
||||
AssignHandle( parent.Handle );
|
||||
NativeMethods.SetGestureConfig( parent.Handle, m_configs );
|
||||
|
||||
}
|
||||
|
||||
public void LoadMultitouch()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
Action a = () =>
|
||||
{
|
||||
if (!RegisterTouchWindow(_parent.Handle, 0))
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
_parent.Invoke(a);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
private void OnHandleCreated( object sender, EventArgs e )
|
||||
{
|
||||
// Window is now created, assign handle to NativeWindow.
|
||||
var control = sender as Control;
|
||||
if ( control != null )
|
||||
{
|
||||
Initialize( control );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHandleDestroyed( object sender, EventArgs e )
|
||||
{
|
||||
// Window was destroyed, release hook.
|
||||
ReleaseHandle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WndProc
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the default window procedure associated with this window.
|
||||
/// </summary>
|
||||
/// <param name="m">A <see cref="T:System.Windows.Forms.Message"/> that is associated with the current Windows message.</param>
|
||||
[PermissionSet( SecurityAction.Demand, Name = "FullTrust" )]
|
||||
protected override void WndProc( ref Message m )
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
// Listen for operating system messages
|
||||
switch ( m.Msg )
|
||||
{
|
||||
case WindowMessage.WM_GESTURE:
|
||||
GestureInfo info;
|
||||
if ( NativeMethods.GetGestureInfo( m.LParam, out info ) )
|
||||
{
|
||||
switch ( (GestureId)info.id )
|
||||
{
|
||||
case GestureId.Pan:
|
||||
handled = OnPan( info );
|
||||
break;
|
||||
case GestureId.PressAndTap:
|
||||
handled = OnPressAndTap( info );
|
||||
break;
|
||||
case GestureId.Rotate:
|
||||
handled = OnRotate( info );
|
||||
break;
|
||||
case GestureId.TwoFingerTap:
|
||||
handled = OnTwoFingerTap( info );
|
||||
break;
|
||||
case GestureId.Zoom:
|
||||
handled = OnZoom( info );
|
||||
break;
|
||||
}
|
||||
if ( handled )
|
||||
{
|
||||
NativeMethods.CloseGestureInfoHandle( m.LParam );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WindowMessage.WM_TOUCH:
|
||||
MessageBox.Show("touch");
|
||||
this.DecodeTouch(ref m);
|
||||
break;
|
||||
//case WindowMessage.WM_POINTERUPDATE:
|
||||
// MessageBox.Show("ptr");
|
||||
// break;
|
||||
}
|
||||
if ( !handled )
|
||||
{
|
||||
base.WndProc( ref m );
|
||||
}
|
||||
}
|
||||
private static int LoWord(int number)
|
||||
{
|
||||
return (number & 0xffff);
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct TOUCHINPUT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public System.IntPtr hSource;
|
||||
public int dwID;
|
||||
public int dwFlags;
|
||||
public int dwMask;
|
||||
public int dwTime;
|
||||
public System.IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct POINTS
|
||||
{
|
||||
public short x;
|
||||
public short y;
|
||||
}
|
||||
public event EventHandler<WMTouchEventArgs> Touchdown; // touch down event handler
|
||||
public event EventHandler<WMTouchEventArgs> Touchup; // touch up event handler
|
||||
public event EventHandler<WMTouchEventArgs> TouchMove; // touch move event handler
|
||||
|
||||
// EventArgs passed to Touch handlers
|
||||
public class WMTouchEventArgs : System.EventArgs
|
||||
{
|
||||
// Private data members
|
||||
private int x; // touch x client coordinate in pixels
|
||||
private int y; // touch y client coordinate in pixels
|
||||
private int id; // contact ID
|
||||
private int mask; // mask which fields in the structure are valid
|
||||
private int flags; // flags
|
||||
private int time; // touch event time
|
||||
private int contactX; // x size of the contact area in pixels
|
||||
private int contactY; // y size of the contact area in pixels
|
||||
|
||||
// Access to data members
|
||||
public int LocationX
|
||||
{
|
||||
get { return x; }
|
||||
set { x = value; }
|
||||
}
|
||||
public int LocationY
|
||||
{
|
||||
get { return y; }
|
||||
set { y = value; }
|
||||
}
|
||||
public int Id
|
||||
{
|
||||
get { return id; }
|
||||
set { id = value; }
|
||||
}
|
||||
public int Flags
|
||||
{
|
||||
get { return flags; }
|
||||
set { flags = value; }
|
||||
}
|
||||
public int Mask
|
||||
{
|
||||
get { return mask; }
|
||||
set { mask = value; }
|
||||
}
|
||||
public int Time
|
||||
{
|
||||
get { return time; }
|
||||
set { time = value; }
|
||||
}
|
||||
public int ContactX
|
||||
{
|
||||
get { return contactX; }
|
||||
set { contactX = value; }
|
||||
}
|
||||
public int ContactY
|
||||
{
|
||||
get { return contactY; }
|
||||
set { contactY = value; }
|
||||
}
|
||||
public bool IsPrimaryContact
|
||||
{
|
||||
get { return (flags & WindowMessage.TOUCHEVENTF_PRIMARY) != 0; }
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public WMTouchEventArgs()
|
||||
{
|
||||
}
|
||||
}
|
||||
[DllImport("user32")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
[DllImport("user32")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern void CloseTouchInputHandle(System.IntPtr lParam);
|
||||
public bool DecodeTouch(ref Message m)
|
||||
{
|
||||
// More than one touchinput may be associated with a touch message,
|
||||
// so an array is needed to get all event information.
|
||||
int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages
|
||||
|
||||
TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures
|
||||
inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages
|
||||
|
||||
// Unpack message parameters into the array of TOUCHINPUT structures, each
|
||||
// representing a message for one single contact.
|
||||
if (!GetTouchInputInfo(m.LParam, inputCount, inputs, _touchInputSize))
|
||||
{
|
||||
// Get touch info failed.
|
||||
return false;
|
||||
}
|
||||
|
||||
// For each contact, dispatch the message to the appropriate message
|
||||
// handler.
|
||||
bool handled = false; // Boolean, is message handled
|
||||
for (int i = 0; i < inputCount; i++)
|
||||
{
|
||||
TOUCHINPUT ti = inputs[i];
|
||||
|
||||
// Assign a handler to this message.
|
||||
EventHandler<WMTouchEventArgs> handler = null; // Touch event handler
|
||||
if ((ti.dwFlags & WindowMessage.TOUCHEVENTF_DOWN) != 0)
|
||||
{
|
||||
handler = Touchdown;
|
||||
}
|
||||
else if ((ti.dwFlags & WindowMessage.TOUCHEVENTF_UP) != 0)
|
||||
{
|
||||
handler = Touchup;
|
||||
}
|
||||
else if ((ti.dwFlags & WindowMessage.TOUCHEVENTF_MOVE) != 0)
|
||||
{
|
||||
handler = TouchMove;
|
||||
}
|
||||
|
||||
// Convert message parameters into touch event arguments and handle the event.
|
||||
if (handler != null)
|
||||
{
|
||||
// Convert the raw touchinput message into a touchevent.
|
||||
WMTouchEventArgs te = new WMTouchEventArgs(); // Touch event arguments
|
||||
|
||||
// TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels.
|
||||
// Also convert screen to client coordinates.
|
||||
te.ContactY = ti.cyContact / 100;
|
||||
te.ContactX = ti.cxContact / 100;
|
||||
te.Id = ti.dwID;
|
||||
{
|
||||
Point pt = _parent.PointToClient(new Point(ti.x / 100, ti.y / 100));
|
||||
te.LocationX = pt.X;
|
||||
te.LocationY = pt.Y;
|
||||
}
|
||||
te.Time = ti.dwTime;
|
||||
te.Mask = ti.dwMask;
|
||||
te.Flags = ti.dwFlags;
|
||||
|
||||
// Invoke the event handler.
|
||||
handler(this, te);
|
||||
|
||||
// Mark this event as handled.
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
CloseTouchInputHandle(m.LParam);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
private bool OnPan( GestureInfo info )
|
||||
{
|
||||
if ( Pan != null )
|
||||
{
|
||||
if ( info.Begin )
|
||||
{
|
||||
_lastPanPoint = new Point( info.location.x, info.location.y );
|
||||
}
|
||||
var args = new PanEventArgs( info, _lastPanPoint );
|
||||
_lastPanPoint = new Point( info.location.x, info.location.y );
|
||||
Pan( this, args );
|
||||
return args.Handled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnPressAndTap( GestureInfo info )
|
||||
{
|
||||
if ( PressAndTap != null )
|
||||
{
|
||||
var args = new PressAndTapEventArgs( info );
|
||||
PressAndTap( this, args );
|
||||
return args.Handled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnRotate( GestureInfo info )
|
||||
{
|
||||
if ( Rotate != null )
|
||||
{
|
||||
if ( info.Begin )
|
||||
{
|
||||
_lastRotation = 0;
|
||||
}
|
||||
var args = new RotateEventArgs( info, _lastRotation );
|
||||
if ( !info.Begin )
|
||||
{
|
||||
// First rotation is the angle the fingers are at, so don't use it
|
||||
_lastRotation = args.TotalAngle;
|
||||
}
|
||||
Rotate( this, args );
|
||||
return args.Handled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnTwoFingerTap( GestureInfo info )
|
||||
{
|
||||
if ( TwoFingerTap != null )
|
||||
{
|
||||
var args = new TwoFingerTapEventArgs( info );
|
||||
TwoFingerTap( this, args );
|
||||
return args.Handled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool OnZoom( GestureInfo info )
|
||||
{
|
||||
if ( Zoom != null )
|
||||
{
|
||||
if ( info.Begin )
|
||||
{
|
||||
_lastZoom = info.arguments;
|
||||
}
|
||||
var args = new ZoomEventArgs( info, _lastZoom );
|
||||
_lastZoom = args.Distance;
|
||||
Zoom( this, args );
|
||||
return args.Handled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
341
framework/MaterialSkin.Core/Gesture/NativeMethods.cs
Normal file
341
framework/MaterialSkin.Core/Gesture/NativeMethods.cs
Normal file
@@ -0,0 +1,341 @@
|
||||
#region The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2011 Robert Prouse http://www.alteridem.net
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
// Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
#region Using Directives
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace MaterialSkin.Gesture
|
||||
{
|
||||
internal static class NativeMethods
|
||||
{
|
||||
#region Private Delegates
|
||||
|
||||
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
||||
private delegate bool GetGestureInfoPtr( IntPtr gestureInfoHandle, ref GestureInfo pGestureInfo );
|
||||
|
||||
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
||||
private delegate bool CloseGestureInfoHandlePtr( IntPtr gestureInfoHandle );
|
||||
|
||||
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
||||
private delegate bool SetGestureConfigPtr( IntPtr hwnd, uint reserved, uint ids, GestureConfig[] configs, uint size );
|
||||
|
||||
private static readonly GetGestureInfoPtr _pGetGestureInfoPtr;
|
||||
private static readonly CloseGestureInfoHandlePtr _pCloseGestureInfoHandle;
|
||||
private static readonly SetGestureConfigPtr _pSetGestureConfig;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Construction
|
||||
|
||||
static NativeMethods()
|
||||
{
|
||||
var user32 = new UnmanagedLibrary( "user32" );
|
||||
_pGetGestureInfoPtr = user32.GetUnmanagedFunction<GetGestureInfoPtr>( "GetGestureInfo" );
|
||||
_pCloseGestureInfoHandle = user32.GetUnmanagedFunction<CloseGestureInfoHandlePtr>( "CloseGestureInfoHandle" );
|
||||
_pSetGestureConfig = user32.GetUnmanagedFunction<SetGestureConfigPtr>( "SetGestureConfig" );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Interface
|
||||
|
||||
/// <summary>
|
||||
/// Registers the HWND to receive all gestures.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx
|
||||
/// </remarks>
|
||||
/// <param name="hwnd">The HWND.</param>
|
||||
/// <returns></returns>
|
||||
public static bool SetGestureConfig( IntPtr hwnd )
|
||||
{
|
||||
if ( _pSetGestureConfig == null )
|
||||
return false;
|
||||
|
||||
var configs = new[] { new GestureConfig( 0, GestureConfigurationFlag.GC_ALLGESTURES, 0 ) };
|
||||
return SetGestureConfig(hwnd, configs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the HWND to receive specific gestures.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx
|
||||
/// </remarks>
|
||||
/// <param name="hwnd">The HWND.</param>
|
||||
/// <param name="configs">The gesture configurations</param>
|
||||
/// <returns></returns>
|
||||
public static bool SetGestureConfig( IntPtr hwnd, GestureConfig[] configs )
|
||||
{
|
||||
return _pSetGestureConfig( hwnd, 0, 1, configs, (uint)Marshal.SizeOf( typeof( GestureConfig ) ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gesture info.
|
||||
/// </summary>
|
||||
/// <param name="gestureInfoHandle">The gesture info handle.</param>
|
||||
/// <param name="gestureInfo">The gesture info.</param>
|
||||
/// <returns></returns>
|
||||
public static bool GetGestureInfo( IntPtr gestureInfoHandle, out GestureInfo gestureInfo )
|
||||
{
|
||||
gestureInfo = new GestureInfo();
|
||||
|
||||
if ( _pGetGestureInfoPtr == null )
|
||||
return false;
|
||||
|
||||
gestureInfo.size = Marshal.SizeOf( gestureInfo );
|
||||
return _pGetGestureInfoPtr( gestureInfoHandle, ref gestureInfo );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the gesture info handle.
|
||||
/// </summary>
|
||||
/// <param name="gestureInfoHandle">The gesture info handle.</param>
|
||||
/// <returns></returns>
|
||||
public static bool CloseGestureInfoHandle( IntPtr gestureInfoHandle )
|
||||
{
|
||||
if ( _pCloseGestureInfoHandle == null )
|
||||
return false;
|
||||
|
||||
return _pCloseGestureInfoHandle( gestureInfoHandle );
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture configuration flags
|
||||
/// </summary>
|
||||
internal static class GestureConfigurationFlag
|
||||
{
|
||||
public const int GC_ALLGESTURES = 0x00000001;
|
||||
public const int GC_ZOOM = 0x00000001;
|
||||
public const int GC_PAN = 0x00000001;
|
||||
public const int GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = 0x00000002;
|
||||
public const int GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = 0x00000004;
|
||||
public const int GC_PAN_WITH_GUTTER = 0x00000008;
|
||||
public const int GC_PAN_WITH_INERTIA = 0x00000010;
|
||||
public const int GC_ROTATE = 0x00000001;
|
||||
public const int GC_TWOFINGERTAP = 0x00000001;
|
||||
public const int GC_PRESSANDTAP = 0x00000001;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture flags - GestureInfo.flags
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum GestureFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// GF_BEGIN
|
||||
/// </summary>
|
||||
Begin = 0x1,
|
||||
/// <summary>
|
||||
/// GF_INERTIA
|
||||
/// </summary>
|
||||
Inertia = 0x2,
|
||||
/// <summary>
|
||||
/// GF_END
|
||||
/// </summary>
|
||||
End = 0x4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture IDs - GestureInfo.id
|
||||
/// </summary>
|
||||
public enum GestureId
|
||||
{
|
||||
/// <summary>
|
||||
/// GID_BEGIN
|
||||
/// </summary>
|
||||
Begin = 1,
|
||||
/// <summary>
|
||||
/// GID_END
|
||||
/// </summary>
|
||||
End = 2,
|
||||
/// <summary>
|
||||
/// GID_ZOOM
|
||||
/// </summary>
|
||||
Zoom = 3,
|
||||
/// <summary>
|
||||
/// GID_PAN
|
||||
/// </summary>
|
||||
Pan = 4,
|
||||
/// <summary>
|
||||
/// GID_ROTATE
|
||||
/// </summary>
|
||||
Rotate = 5,
|
||||
/// <summary>
|
||||
/// GID_TWOFINGERTAP
|
||||
/// </summary>
|
||||
TwoFingerTap = 6,
|
||||
/// <summary>
|
||||
/// GID_PRESSANDTAP
|
||||
/// </summary>
|
||||
PressAndTap = 7
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Window Messages
|
||||
/// </summary>
|
||||
internal static class WindowMessage
|
||||
{
|
||||
public const int WM_TOUCH = 0x0240;
|
||||
public const int WM_POINTERUPDATE =0x0245;
|
||||
public const int WM_GESTURE = 0x0119;
|
||||
public const int WM_GESTURENOTIFY = 0x011A;
|
||||
public const int TOUCHEVENTF_MOVE = 0x0001;
|
||||
public const int TOUCHEVENTF_DOWN = 0x0002;
|
||||
public const int TOUCHEVENTF_UP = 0x0004;
|
||||
public const int TOUCHEVENTF_INRANGE = 0x0008;
|
||||
public const int TOUCHEVENTF_PRIMARY = 0x0010;
|
||||
public const int TOUCHEVENTF_NOCOALESCE = 0x0020;
|
||||
public const int TOUCHEVENTF_PEN = 0x0040;
|
||||
|
||||
// Touch input mask values (TOUCHINPUT.dwMask) [winuser.h]
|
||||
public const int TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001; // the dwTime field contains a system generated value
|
||||
public const int TOUCHINPUTMASKF_EXTRAINFO = 0x0002; // the dwExtraInfo field is valid
|
||||
public const int TOUCHINPUTMASKF_CONTACTAREA = 0x0004; // the cxContact and cyContact fields are valid
|
||||
|
||||
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public struct Points
|
||||
{
|
||||
public short x;
|
||||
public short y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gesture configuration structure
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used in SetGestureConfig and GetGestureConfig
|
||||
/// http://msdn.microsoft.com/en-us/library/windows/desktop/dd353231%28v=vs.85%29.aspx
|
||||
/// </remarks>
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public struct GestureConfig
|
||||
{
|
||||
public GestureConfig( uint id, uint want, uint block )
|
||||
{
|
||||
Id = id;
|
||||
Want = want;
|
||||
Block = block;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The identifier for the type of configuration that will have messages enabled or disabled.
|
||||
/// </summary>
|
||||
public uint Id;
|
||||
|
||||
/// <summary>
|
||||
/// The messages to enable.
|
||||
/// </summary>
|
||||
public uint Want;
|
||||
|
||||
/// <summary>
|
||||
/// The messages to disable.
|
||||
/// </summary>
|
||||
public uint Block;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores information about a gesture.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the
|
||||
/// GetGestureInfo function to retrieve this information.
|
||||
/// - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE
|
||||
/// message lParam into the GetGestureExtraArgs function to retrieve extended
|
||||
/// argument information.
|
||||
/// </remarks>
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public struct GestureInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the structure, in bytes. The caller must set this.
|
||||
/// </summary>
|
||||
public int size;
|
||||
/// <summary>
|
||||
/// The state of the gesture. Contains GestureFlags.
|
||||
/// </summary>
|
||||
public int flags;
|
||||
/// <summary>
|
||||
/// The identifier of the gesture command. Contains GestureId.
|
||||
/// </summary>
|
||||
public int id;
|
||||
/// <summary>
|
||||
/// A handle to the window that is targeted by this gesture.
|
||||
/// </summary>
|
||||
public IntPtr hwnd;
|
||||
/// <summary>
|
||||
/// A Points structure containing the coordinates associated with the gesture. These coordinates are always relative to the origin of the screen.
|
||||
/// </summary>
|
||||
public Points location;
|
||||
/// <summary>
|
||||
/// An internally used identifier for the structure.
|
||||
/// </summary>
|
||||
public int instanceId;
|
||||
/// <summary>
|
||||
/// An internally used identifier for the sequence.
|
||||
/// </summary>
|
||||
public int sequenceId;
|
||||
/// <summary>
|
||||
/// A 64-bit unsigned integer that contains the arguments for gestures that fit into 8 bytes.
|
||||
/// </summary>
|
||||
public Int64 arguments;
|
||||
/// <summary>
|
||||
/// The size, in bytes, of extra arguments that accompany this gesture.
|
||||
/// </summary>
|
||||
public int extraArguments;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="GestureFlags"/> Begin is set.
|
||||
/// </summary>
|
||||
public bool Begin
|
||||
{
|
||||
get { return ((GestureFlags)flags & GestureFlags.Begin) == GestureFlags.Begin; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="GestureFlags"/> End is set.
|
||||
/// </summary>
|
||||
public bool End
|
||||
{
|
||||
get { return ((GestureFlags)flags & GestureFlags.End) == GestureFlags.End; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="GestureFlags"/> Inertia is set
|
||||
/// </summary>
|
||||
public bool Inertia
|
||||
{
|
||||
get { return ((GestureFlags)flags & GestureFlags.Inertia) == GestureFlags.Inertia; }
|
||||
}
|
||||
}
|
||||
}
|
||||
142
framework/MaterialSkin.Core/Gesture/UnmanagedLibrary.cs
Normal file
142
framework/MaterialSkin.Core/Gesture/UnmanagedLibrary.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
#region Copyright (c) Microsoft Corporation.
|
||||
//
|
||||
// The source code of UnmanagedLibrary.cs is quoted from Mike Stall's article:
|
||||
//
|
||||
// Type-safe Managed wrappers for kernel32!GetProcAddress
|
||||
// http://blogs.msdn.com/jmstall/archive/2007/01/06/Typesafe-GetProcAddress.aspx
|
||||
//
|
||||
// This source is subject to the Microsoft Public License.
|
||||
// See http://www.opensource.org/licenses/MS-PL.
|
||||
// All other rights reserved.
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
||||
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
#region Using Directives
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace MaterialSkin.Gesture
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class to wrap an unmanaged DLL and be responsible for freeing it.
|
||||
/// </summary>
|
||||
/// <remarks>This is a managed wrapper over the native LoadLibrary, GetProcAddress, and
|
||||
/// FreeLibrary calls.
|
||||
/// </remarks>
|
||||
public sealed class UnmanagedLibrary : IDisposable
|
||||
{
|
||||
#region Safe Handles and Native imports
|
||||
|
||||
// See http://msdn.microsoft.com/msdnmag/issues/05/10/Reliability/ for more about safe handles.
|
||||
[SecurityPermission( SecurityAction.LinkDemand, UnmanagedCode = true )]
|
||||
sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeLibraryHandle() : base( true ) { }
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.FreeLibrary( handle );
|
||||
}
|
||||
}
|
||||
|
||||
static class NativeMethods
|
||||
{
|
||||
const string KERNEL32 = "kernel32";
|
||||
[DllImport( KERNEL32, CharSet = CharSet.Auto, BestFitMapping = false, SetLastError = true )]
|
||||
public static extern SafeLibraryHandle LoadLibrary( string fileName );
|
||||
|
||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||
[DllImport( KERNEL32, SetLastError = true )]
|
||||
[return: MarshalAs( UnmanagedType.Bool )]
|
||||
public static extern bool FreeLibrary( IntPtr hModule );
|
||||
|
||||
[DllImport( KERNEL32 )]
|
||||
public static extern IntPtr GetProcAddress( SafeLibraryHandle hModule, String procname );
|
||||
}
|
||||
|
||||
#endregion // Safe Handles and Native imports
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to load a dll and be responible for freeing it.
|
||||
/// </summary>
|
||||
/// <param name="fileName">full path name of dll to load</param>
|
||||
/// <exception cref="FileNotFoundException">if fileName can't be found</exception>
|
||||
/// <remarks>Throws exceptions on failure. Most common failure would be file-not-found, or
|
||||
/// that the file is not a loadable image.</remarks>
|
||||
public UnmanagedLibrary( string fileName )
|
||||
{
|
||||
m_hLibrary = NativeMethods.LoadLibrary( fileName );
|
||||
if ( m_hLibrary.IsInvalid )
|
||||
{
|
||||
int hr = Marshal.GetHRForLastWin32Error();
|
||||
Marshal.ThrowExceptionForHR( hr );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dynamically lookup a function in the dll via kernel32!GetProcAddress.
|
||||
/// </summary>
|
||||
/// <param name="functionName">raw name of the function in the export table.</param>
|
||||
/// <returns>null if function is not found. Else a delegate to the unmanaged function.
|
||||
/// </returns>
|
||||
/// <remarks>GetProcAddress results are valid as long as the dll is not yet unloaded. This
|
||||
/// is very very dangerous to use since you need to ensure that the dll is not unloaded
|
||||
/// until after you're done with any objects implemented by the dll. For example, if you
|
||||
/// get a delegate that then gets an IUnknown implemented by this dll,
|
||||
/// you can not dispose this library until that IUnknown is collected. Else, you may free
|
||||
/// the library and then the CLR may call release on that IUnknown and it will crash.</remarks>
|
||||
public TDelegate GetUnmanagedFunction<TDelegate>( string functionName ) where TDelegate : class
|
||||
{
|
||||
IntPtr p = NativeMethods.GetProcAddress( m_hLibrary, functionName );
|
||||
|
||||
// Failure is a common case, especially for adaptive code.
|
||||
if ( p == IntPtr.Zero )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Delegate function = Marshal.GetDelegateForFunctionPointer( p, typeof( TDelegate ) );
|
||||
|
||||
// Ideally, we'd just make the constraint on TDelegate be
|
||||
// System.Delegate, but compiler error CS0702 (constrained can't be System.Delegate)
|
||||
// prevents that. So we make the constraint system.object and do the cast from object-->TDelegate.
|
||||
object o = function;
|
||||
|
||||
return (TDelegate)o;
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
/// <summary>
|
||||
/// Call FreeLibrary on the unmanaged dll. All function pointers
|
||||
/// handed out from this class become invalid after this.
|
||||
/// </summary>
|
||||
/// <remarks>This is very dangerous because it suddenly invalidate
|
||||
/// everything retrieved from this dll. This includes any functions
|
||||
/// handed out via GetProcAddress, and potentially any objects returned
|
||||
/// from those functions (which may have an implemention in the
|
||||
/// dll).
|
||||
/// </remarks>
|
||||
public void Dispose()
|
||||
{
|
||||
if ( !m_hLibrary.IsClosed )
|
||||
{
|
||||
m_hLibrary.Close();
|
||||
}
|
||||
}
|
||||
|
||||
// Unmanaged resource. CLR will ensure SafeHandles get freed, without requiring a finalizer on this class.
|
||||
SafeLibraryHandle m_hLibrary;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
17
framework/MaterialSkin.Core/IMaterialControl.cs
Normal file
17
framework/MaterialSkin.Core/IMaterialControl.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace MaterialSkin
|
||||
{
|
||||
public interface IMaterialControl
|
||||
{
|
||||
int Depth { get; set; }
|
||||
MaterialSkinManager SkinManager { get; }
|
||||
MouseState MouseState { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public enum MouseState
|
||||
{
|
||||
HOVER,
|
||||
DOWN,
|
||||
OUT
|
||||
}
|
||||
}
|
||||
117
framework/MaterialSkin.Core/MaterialSkin.Core.csproj
Normal file
117
framework/MaterialSkin.Core/MaterialSkin.Core.csproj
Normal file
@@ -0,0 +1,117 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\Roboto-Medium.ttf" />
|
||||
<None Remove="Resources\Roboto-Regular.ttf" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Roboto-Medium.ttf" />
|
||||
<EmbeddedResource Include="Resources\Roboto-Regular.ttf" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Controls\MaterialCheckBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialComboBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialContextMenuStrip.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialDivider.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialFlatButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialIcon.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialIndicator.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialIndicator.Designer.cs">
|
||||
<DependentUpon>MaterialIndicator.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialLabel.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialListView.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialLoader.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialLoader.Designer.cs">
|
||||
<DependentUpon>MaterialLoader.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialMessageBox.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialMessageBox.Designer.cs">
|
||||
<DependentUpon>MaterialMessageBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialPanel.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialProgressBar.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialRadioButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialRaisedButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialSingleLineTextField.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialTabControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialTabSelector.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialUpDown.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Controls\MaterialUpDown.Designer.cs">
|
||||
<DependentUpon>MaterialUpDown.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Resources\Resource1.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resource1.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Controls\MaterialIndicator.resx">
|
||||
<DependentUpon>MaterialIndicator.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Controls\MaterialLoader.resx">
|
||||
<DependentUpon>MaterialLoader.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Controls\MaterialMessageBox.resx">
|
||||
<DependentUpon>MaterialMessageBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Controls\MaterialUpDown.resx">
|
||||
<DependentUpon>MaterialUpDown.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resources\Resource1.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resource1.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
349
framework/MaterialSkin.Core/MaterialSkinManager.cs
Normal file
349
framework/MaterialSkin.Core/MaterialSkinManager.cs
Normal file
@@ -0,0 +1,349 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using MaterialSkin.Controls;
|
||||
using MaterialSkin.Core.Resources;
|
||||
|
||||
|
||||
namespace MaterialSkin
|
||||
{
|
||||
public class MaterialSkinManager
|
||||
{
|
||||
public static void ConfigureForInspectron()
|
||||
{
|
||||
Instance.ColorScheme = new ColorScheme(Primary.Red800, Primary.Red800, Primary.Red400, Accent.Red200, TextShade.BLACK);
|
||||
|
||||
}
|
||||
|
||||
//Singleton instance
|
||||
private static MaterialSkinManager _instance;
|
||||
|
||||
//Forms to control
|
||||
private readonly List<MaterialForm> _formsToManage = new List<MaterialForm>();
|
||||
|
||||
//Theme
|
||||
private Themes _theme;
|
||||
public Themes Theme
|
||||
{
|
||||
get { return _theme; }
|
||||
set
|
||||
{
|
||||
_theme = value;
|
||||
UpdateBackgrounds();
|
||||
}
|
||||
}
|
||||
|
||||
private ColorScheme _colorScheme;
|
||||
public ColorScheme ColorScheme
|
||||
{
|
||||
get { return _colorScheme; }
|
||||
set
|
||||
{
|
||||
_colorScheme = value;
|
||||
UpdateBackgrounds();
|
||||
}
|
||||
}
|
||||
|
||||
public enum Themes : byte
|
||||
{
|
||||
LIGHT,
|
||||
DARK
|
||||
}
|
||||
|
||||
//Constant color values
|
||||
private static readonly Color PRIMARY_TEXT_BLACK = Color.FromArgb(222, 0, 0, 0);
|
||||
private static readonly Brush PRIMARY_TEXT_BLACK_BRUSH = new SolidBrush(PRIMARY_TEXT_BLACK);
|
||||
public static Color SECONDARY_TEXT_BLACK = Color.FromArgb(138, 0, 0, 0);
|
||||
public static Brush SECONDARY_TEXT_BLACK_BRUSH = new SolidBrush(SECONDARY_TEXT_BLACK);
|
||||
private static readonly Color DISABLED_OR_HINT_TEXT_BLACK = Color.FromArgb(66, 0, 0, 0);
|
||||
private static readonly Brush DISABLED_OR_HINT_TEXT_BLACK_BRUSH = new SolidBrush(DISABLED_OR_HINT_TEXT_BLACK);
|
||||
private static readonly Color DIVIDERS_BLACK = Color.FromArgb(31, 0, 0, 0);
|
||||
private static readonly Brush DIVIDERS_BLACK_BRUSH = new SolidBrush(DIVIDERS_BLACK);
|
||||
|
||||
private static readonly Color PRIMARY_TEXT_WHITE = Color.FromArgb(255, 255, 255, 255);
|
||||
private static readonly Brush PRIMARY_TEXT_WHITE_BRUSH = new SolidBrush(PRIMARY_TEXT_WHITE);
|
||||
public static Color SECONDARY_TEXT_WHITE = Color.FromArgb(179, 255, 255, 255);
|
||||
public static Brush SECONDARY_TEXT_WHITE_BRUSH = new SolidBrush(SECONDARY_TEXT_WHITE);
|
||||
private static readonly Color DISABLED_OR_HINT_TEXT_WHITE = Color.FromArgb(77, 255, 255, 255);
|
||||
private static readonly Brush DISABLED_OR_HINT_TEXT_WHITE_BRUSH = new SolidBrush(DISABLED_OR_HINT_TEXT_WHITE);
|
||||
private static readonly Color DIVIDERS_WHITE = Color.FromArgb(31, 255, 255, 255);
|
||||
private static readonly Brush DIVIDERS_WHITE_BRUSH = new SolidBrush(DIVIDERS_WHITE);
|
||||
|
||||
// Checkbox colors
|
||||
private static readonly Color CHECKBOX_OFF_LIGHT = Color.FromArgb(138, 0, 0, 0);
|
||||
private static readonly Brush CHECKBOX_OFF_LIGHT_BRUSH = new SolidBrush(CHECKBOX_OFF_LIGHT);
|
||||
private static readonly Color CHECKBOX_OFF_DISABLED_LIGHT = Color.FromArgb(66, 0, 0, 0);
|
||||
private static readonly Brush CHECKBOX_OFF_DISABLED_LIGHT_BRUSH = new SolidBrush(CHECKBOX_OFF_DISABLED_LIGHT);
|
||||
|
||||
private static readonly Color CHECKBOX_OFF_DARK = Color.FromArgb(179, 255, 255, 255);
|
||||
private static readonly Brush CHECKBOX_OFF_DARK_BRUSH = new SolidBrush(CHECKBOX_OFF_DARK);
|
||||
private static readonly Color CHECKBOX_OFF_DISABLED_DARK = Color.FromArgb(77, 255, 255, 255);
|
||||
private static readonly Brush CHECKBOX_OFF_DISABLED_DARK_BRUSH = new SolidBrush(CHECKBOX_OFF_DISABLED_DARK);
|
||||
|
||||
//Raised button
|
||||
private static readonly Color RAISED_BUTTON_BACKGROUND = Color.FromArgb(255, 255, 255, 255);
|
||||
private static readonly Brush RAISED_BUTTON_BACKGROUND_BRUSH = new SolidBrush(RAISED_BUTTON_BACKGROUND);
|
||||
private static readonly Color RAISED_BUTTON_TEXT_LIGHT = PRIMARY_TEXT_WHITE;
|
||||
private static readonly Brush RAISED_BUTTON_TEXT_LIGHT_BRUSH = new SolidBrush(RAISED_BUTTON_TEXT_LIGHT);
|
||||
private static readonly Color RAISED_BUTTON_TEXT_DARK = PRIMARY_TEXT_BLACK;
|
||||
private static readonly Brush RAISED_BUTTON_TEXT_DARK_BRUSH = new SolidBrush(RAISED_BUTTON_TEXT_DARK);
|
||||
|
||||
//Flat button
|
||||
private static readonly Color FLAT_BUTTON_BACKGROUND_HOVER_LIGHT = Color.FromArgb(20.PercentageToColorComponent(), 0x999999.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_BACKGROUND_HOVER_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_HOVER_LIGHT);
|
||||
private static readonly Color FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT = Color.FromArgb(40.PercentageToColorComponent(), 0x999999.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT);
|
||||
private static readonly Color FLAT_BUTTON_DISABLEDTEXT_LIGHT = Color.FromArgb(26.PercentageToColorComponent(), 0x000000.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_DISABLEDTEXT_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_DISABLEDTEXT_LIGHT);
|
||||
|
||||
private static readonly Color FLAT_BUTTON_BACKGROUND_HOVER_DARK = Color.FromArgb(15.PercentageToColorComponent(), 0xCCCCCC.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_BACKGROUND_HOVER_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_HOVER_DARK);
|
||||
private static readonly Color FLAT_BUTTON_BACKGROUND_PRESSED_DARK = Color.FromArgb(25.PercentageToColorComponent(), 0xCCCCCC.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_BACKGROUND_PRESSED_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_PRESSED_DARK);
|
||||
private static readonly Color FLAT_BUTTON_DISABLEDTEXT_DARK = Color.FromArgb(30.PercentageToColorComponent(), 0xFFFFFF.ToColor());
|
||||
private static readonly Brush FLAT_BUTTON_DISABLEDTEXT_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_DISABLEDTEXT_DARK);
|
||||
|
||||
//ContextMenuStrip
|
||||
private static readonly Color CMS_BACKGROUND_LIGHT_HOVER = Color.FromArgb(255, 238, 238, 238);
|
||||
private static readonly Brush CMS_BACKGROUND_HOVER_LIGHT_BRUSH = new SolidBrush(CMS_BACKGROUND_LIGHT_HOVER);
|
||||
|
||||
private static readonly Color CMS_BACKGROUND_DARK_HOVER = Color.FromArgb(38, 204, 204, 204);
|
||||
private static readonly Brush CMS_BACKGROUND_HOVER_DARK_BRUSH = new SolidBrush(CMS_BACKGROUND_DARK_HOVER);
|
||||
|
||||
//Application background
|
||||
private static readonly Color BACKGROUND_LIGHT = Color.FromArgb(255, 255, 255, 255);
|
||||
private static Brush BACKGROUND_LIGHT_BRUSH = new SolidBrush(BACKGROUND_LIGHT);
|
||||
|
||||
private static readonly Color BACKGROUND_DARK = Color.FromArgb(255, 51, 51, 51);
|
||||
private static Brush BACKGROUND_DARK_BRUSH = new SolidBrush(BACKGROUND_DARK);
|
||||
|
||||
//Application action bar
|
||||
public readonly Color ACTION_BAR_TEXT = Color.FromArgb(255, 255, 255, 255);
|
||||
public readonly Brush ACTION_BAR_TEXT_BRUSH = new SolidBrush(Color.FromArgb(255, 255, 255, 255));
|
||||
public readonly Color ACTION_BAR_TEXT_SECONDARY = Color.FromArgb(153, 255, 255, 255);
|
||||
public readonly Brush ACTION_BAR_TEXT_SECONDARY_BRUSH = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
|
||||
|
||||
public Color GetPrimaryTextColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? PRIMARY_TEXT_BLACK : PRIMARY_TEXT_WHITE;
|
||||
}
|
||||
|
||||
public Brush GetPrimaryTextBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? PRIMARY_TEXT_BLACK_BRUSH : PRIMARY_TEXT_WHITE_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetSecondaryTextColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? SECONDARY_TEXT_BLACK : SECONDARY_TEXT_WHITE;
|
||||
}
|
||||
|
||||
public Brush GetSecondaryTextBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? SECONDARY_TEXT_BLACK_BRUSH : SECONDARY_TEXT_WHITE_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetDisabledOrHintColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? DISABLED_OR_HINT_TEXT_BLACK : DISABLED_OR_HINT_TEXT_WHITE;
|
||||
}
|
||||
|
||||
public Brush GetDisabledOrHintBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? DISABLED_OR_HINT_TEXT_BLACK_BRUSH : DISABLED_OR_HINT_TEXT_WHITE_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetDividersColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? DIVIDERS_BLACK : DIVIDERS_WHITE;
|
||||
}
|
||||
|
||||
public Brush GetDividersBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? DIVIDERS_BLACK_BRUSH : DIVIDERS_WHITE_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetCheckboxOffColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? CHECKBOX_OFF_LIGHT : CHECKBOX_OFF_DARK;
|
||||
}
|
||||
|
||||
public Brush GetCheckboxOffBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? CHECKBOX_OFF_LIGHT_BRUSH : CHECKBOX_OFF_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetCheckBoxOffDisabledColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? CHECKBOX_OFF_DISABLED_LIGHT : CHECKBOX_OFF_DISABLED_DARK;
|
||||
}
|
||||
|
||||
public Brush GetCheckBoxOffDisabledBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? CHECKBOX_OFF_DISABLED_LIGHT_BRUSH : CHECKBOX_OFF_DISABLED_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Brush GetRaisedButtonBackgroundBrush()
|
||||
{
|
||||
return RAISED_BUTTON_BACKGROUND_BRUSH;
|
||||
}
|
||||
|
||||
public Brush GetRaisedButtonTextBrush(bool primary)
|
||||
{
|
||||
return primary ? RAISED_BUTTON_TEXT_LIGHT_BRUSH : RAISED_BUTTON_TEXT_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetFlatButtonHoverBackgroundColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_HOVER_LIGHT : FLAT_BUTTON_BACKGROUND_HOVER_DARK;
|
||||
}
|
||||
|
||||
public Brush GetFlatButtonHoverBackgroundBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_HOVER_LIGHT_BRUSH : FLAT_BUTTON_BACKGROUND_HOVER_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetFlatButtonPressedBackgroundColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT : FLAT_BUTTON_BACKGROUND_PRESSED_DARK;
|
||||
}
|
||||
|
||||
public Brush GetFlatButtonPressedBackgroundBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT_BRUSH : FLAT_BUTTON_BACKGROUND_PRESSED_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Brush GetFlatButtonDisabledTextBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? FLAT_BUTTON_DISABLEDTEXT_LIGHT_BRUSH : FLAT_BUTTON_DISABLEDTEXT_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Brush GetCmsSelectedItemBrush()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? CMS_BACKGROUND_HOVER_LIGHT_BRUSH : CMS_BACKGROUND_HOVER_DARK_BRUSH;
|
||||
}
|
||||
|
||||
public Color GetApplicationBackgroundColor()
|
||||
{
|
||||
return Theme == Themes.LIGHT ? BACKGROUND_LIGHT : BACKGROUND_DARK;
|
||||
}
|
||||
|
||||
//Roboto font
|
||||
public Font ROBOTO_MEDIUM_12;
|
||||
public Font ROBOTO_REGULAR_11;
|
||||
public Font ROBOTO_MEDIUM_11;
|
||||
public Font ROBOTO_MEDIUM_10;
|
||||
|
||||
//Other constants
|
||||
public int FORM_PADDING = 14;
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pvd, [In] ref uint pcFonts);
|
||||
|
||||
private MaterialSkinManager()
|
||||
{
|
||||
ROBOTO_MEDIUM_12 = new Font(LoadFont(Resource1.Roboto_Medium), 12f);
|
||||
ROBOTO_MEDIUM_10 = new Font(LoadFont(Resource1.Roboto_Medium), 10f);
|
||||
ROBOTO_REGULAR_11 = new Font(LoadFont(Resource1.Roboto_Regular), 11f);
|
||||
ROBOTO_MEDIUM_11 = new Font(LoadFont(Resource1.Roboto_Medium), 11f);
|
||||
Theme = Themes.LIGHT;
|
||||
ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE);
|
||||
}
|
||||
|
||||
public static MaterialSkinManager Instance => _instance ?? (_instance = new MaterialSkinManager());
|
||||
|
||||
public void AddFormToManage(MaterialForm materialForm)
|
||||
{
|
||||
_formsToManage.Add(materialForm);
|
||||
UpdateBackgrounds();
|
||||
}
|
||||
|
||||
public void RemoveFormToManage(MaterialForm materialForm)
|
||||
{
|
||||
_formsToManage.Remove(materialForm);
|
||||
}
|
||||
|
||||
private readonly PrivateFontCollection privateFontCollection = new PrivateFontCollection();
|
||||
|
||||
private FontFamily LoadFont(byte[] fontResource)
|
||||
{
|
||||
int dataLength = fontResource.Length;
|
||||
IntPtr fontPtr = Marshal.AllocCoTaskMem(dataLength);
|
||||
Marshal.Copy(fontResource, 0, fontPtr, dataLength);
|
||||
|
||||
uint cFonts = 0;
|
||||
AddFontMemResourceEx(fontPtr, (uint)fontResource.Length, IntPtr.Zero, ref cFonts);
|
||||
privateFontCollection.AddMemoryFont(fontPtr, dataLength);
|
||||
|
||||
return privateFontCollection.Families.Last();
|
||||
}
|
||||
|
||||
private void UpdateBackgrounds()
|
||||
{
|
||||
var newBackColor = GetApplicationBackgroundColor();
|
||||
foreach (var materialForm in _formsToManage)
|
||||
{
|
||||
materialForm.BackColor = newBackColor;
|
||||
UpdateControl(materialForm, newBackColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateToolStrip(ToolStrip toolStrip, Color newBackColor)
|
||||
{
|
||||
if (toolStrip == null) return;
|
||||
|
||||
toolStrip.BackColor = newBackColor;
|
||||
foreach (ToolStripItem control in toolStrip.Items)
|
||||
{
|
||||
control.BackColor = newBackColor;
|
||||
if (control is MaterialToolStripMenuItem && (control as MaterialToolStripMenuItem).HasDropDown)
|
||||
{
|
||||
|
||||
//recursive call
|
||||
UpdateToolStrip((control as MaterialToolStripMenuItem).DropDown, newBackColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateControl(Control controlToUpdate, Color newBackColor)
|
||||
{
|
||||
if (controlToUpdate == null) return;
|
||||
|
||||
if (controlToUpdate.ContextMenuStrip != null)
|
||||
{
|
||||
UpdateToolStrip(controlToUpdate.ContextMenuStrip, newBackColor);
|
||||
}
|
||||
var tabControl = controlToUpdate as MaterialTabControl;
|
||||
if (tabControl != null)
|
||||
{
|
||||
foreach (TabPage tabPage in tabControl.TabPages)
|
||||
{
|
||||
tabPage.BackColor = newBackColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (controlToUpdate is MaterialDivider)
|
||||
{
|
||||
controlToUpdate.BackColor = GetDividersColor();
|
||||
}
|
||||
|
||||
if (controlToUpdate is MaterialListView)
|
||||
{
|
||||
controlToUpdate.BackColor = newBackColor;
|
||||
|
||||
}
|
||||
|
||||
//recursive call
|
||||
foreach (Control control in controlToUpdate.Controls)
|
||||
{
|
||||
UpdateControl(control, newBackColor);
|
||||
}
|
||||
|
||||
controlToUpdate.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
113
framework/MaterialSkin.Core/Resources/Resource1.Designer.cs
generated
Normal file
113
framework/MaterialSkin.Core/Resources/Resource1.Designer.cs
generated
Normal file
@@ -0,0 +1,113 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace MaterialSkin.Core.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resource1 {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resource1() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MaterialSkin.Core.Resources.Resource1", typeof(Resource1).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap drop_down_arrow {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("drop_down_arrow", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Roboto_Medium {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Roboto_Medium", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Roboto_Regular {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Roboto_Regular", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap round_delete_button {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("round_delete_button", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap rounded_add_button {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("rounded_add_button", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
136
framework/MaterialSkin.Core/Resources/Resource1.resx
Normal file
136
framework/MaterialSkin.Core/Resources/Resource1.resx
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="drop_down_arrow" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>drop-down-arrow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Roboto_Medium" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>roboto-medium.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Roboto_Regular" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>roboto-regular.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="rounded_add_button" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>rounded-add-button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="round_delete_button" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>round-delete-button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
framework/MaterialSkin.Core/Resources/Roboto-Medium.ttf
Normal file
BIN
framework/MaterialSkin.Core/Resources/Roboto-Medium.ttf
Normal file
Binary file not shown.
BIN
framework/MaterialSkin.Core/Resources/Roboto-Regular.ttf
Normal file
BIN
framework/MaterialSkin.Core/Resources/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
framework/MaterialSkin.Core/Resources/drop-down-arrow.png
Normal file
BIN
framework/MaterialSkin.Core/Resources/drop-down-arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 478 B |
BIN
framework/MaterialSkin.Core/Resources/round-delete-button.png
Normal file
BIN
framework/MaterialSkin.Core/Resources/round-delete-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
framework/MaterialSkin.Core/Resources/rounded-add-button.png
Normal file
BIN
framework/MaterialSkin.Core/Resources/rounded-add-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user