#region License
/* Copyright (c) 2017 Fabrice Lacharme
* This code is inspired from Michal Brylka
* https://www.codeproject.com/Articles/17395/Owner-drawn-trackbar-slider
*
* 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 Contact
/*
* Fabrice Lacharme
* Email: fabrice.lacharme@gmail.com
*/
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace TrackbarKeyEditor
{
/* Original code from Michal Brylka on Code Project
* see https://www.codeproject.com/Articles/17395/Owner-drawn-trackbar-slider
* ColorSlider is a trackbar control written in C# as a replacement of the trackbar
*
* CodeProject: https://www.codeproject.com/Tips/1193311/Csharp-Slider-Trackbar-Control-using-Windows-Forms
* Github: https://github.com/fabricelacharme/ColorSlider
*
* 20/11/17 - version 1.0.O.1
*
* Fixed: erroneous vertical display in case of minimum <> 0 (negative or positive)
* Modified: DrawColorSlider, OnMouseMove
*
* Added: Ticks display transformations
* - TickAdd: allow to add a fixed value to the graduations:
* usage: transform K = °C + 273,15, or °F = 1,8°C + 32 K = (°F + 459,67) / 1,8
* - TickDivide: allow to diveide by a fixed value the graduations
* usage: divide by 1000 => display graduations in kilograms when in gram
*
*
* 10/12/17 - version 1.0.0.2
*
* Added ForeColor property to graduations text color
*
*/
public class KeyFrameThumb
{
public Color Color { get; set; }
public Rectangle Rectangle { get; set; }
public int Frame { get; set; }
public Bitmap bitmap { get; set; }
}
///
/// Encapsulates control that visualy displays certain integer value and allows user to change it within desired range. It imitates as far as mouse usage is concerned.
///
[ToolboxBitmap(typeof(TrackBar))]
[DefaultEvent("Scroll"), DefaultProperty("BarInnerColor")]
public partial class TrackbarKeyEditor : Control
{
#region Events
///
/// Fires when Slider position has changed
///
[Description("Event fires when the Value property changes")]
[Category("Action")]
public event EventHandler ValueChanged;
///
/// Fires when user scrolls the Slider
///
[Description("Event fires when the Slider position is changed")]
[Category("Behavior")]
public event ScrollEventHandler Scroll;
#endregion
#region Properties
private Rectangle barRect; //bounding rectangle of bar area
private Rectangle barHalfRect;
private Rectangle thumbHalfRect;
private Rectangle elapsedRect; //bounding rectangle of elapsed area
public List keyFrameThumbs = new List();
public void AddKeyFrameThumbSlider(int frame, int translateY, int scale, Color color)
{
keyFrameThumbs.Add(new KeyFrameThumb()
{
Rectangle = new Rectangle(new Point(frame, translateY), new Size(scale / 2, scale / 2)),
Color = color,
Frame = frame,
});
}
public void AddKeyFrameThumbSlider(int frame, int translateY, int scale, Image Image)
{
Bitmap bitmap = ResizeImage(Image, scale / 2, scale / 2);
keyFrameThumbs.Add(new KeyFrameThumb()
{
Rectangle = new Rectangle(new Point(frame, translateY), new Size(scale, scale)),
Color = Color.Black,
Frame = frame,
bitmap = bitmap,
});
}
public void ClearKeys()
{
keyFrameThumbs.Clear();
Refresh();
}
#region thumb
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
private Rectangle thumbRect; //bounding rectangle of thumb area
///
/// Gets the thumb rect. Usefull to determine bounding rectangle when creating custom thumb shape.
///
/// The thumb rect.
[Browsable(false)]
public Rectangle ThumbRect
{
get { return thumbRect; }
}
private Size _thumbSize = new Size(16, 16);
///
/// Gets or sets the size of the thumb.
///
/// The size of the thumb.
/// exception thrown when value is lower than zero or grather than half of appropiate dimension
[Description("Set Slider thumb size")]
[Category("ColorSlider")]
[DefaultValue(16)]
public Size ThumbSize
{
get { return _thumbSize; }
set
{
int h = value.Height;
int w = value.Width;
if (h > 0 && w > 0)
{
_thumbSize = new Size(w, h);
}
else
throw new ArgumentOutOfRangeException(
"TrackSize has to be greather than zero and lower than half of Slider width");
Invalidate();
}
}
private GraphicsPath _thumbCustomShape = null;
///
/// Gets or sets the thumb custom shape. Use ThumbRect property to determine bounding rectangle.
///
/// The thumb custom shape. null means default shape
[Description("Set Slider's thumb's custom shape")]
[Category("ColorSlider")]
[Browsable(false)]
[DefaultValue(typeof(GraphicsPath), "null")]
public GraphicsPath ThumbCustomShape
{
get { return _thumbCustomShape; }
set
{
_thumbCustomShape = value;
//_thumbSize = (int) (_barOrientation == Orientation.Horizontal ? value.GetBounds().Width : value.GetBounds().Height) + 1;
_thumbSize = new Size((int)value.GetBounds().Width, (int)value.GetBounds().Height);
Invalidate();
}
}
private Size _thumbRoundRectSize = new Size(16, 16);
///
/// Gets or sets the size of the thumb round rectangle edges.
///
/// The size of the thumb round rectangle edges.
[Description("Set Slider's thumb round rect size")]
[Category("ColorSlider")]
[DefaultValue(typeof(Size), "16; 16")]
public Size ThumbRoundRectSize
{
get { return _thumbRoundRectSize; }
set
{
int h = value.Height, w = value.Width;
if (h <= 0) h = 1;
if (w <= 0) w = 1;
_thumbRoundRectSize = new Size(w, h);
Invalidate();
}
}
private Size _borderRoundRectSize = new Size(8, 8);
///
/// Gets or sets the size of the border round rect.
///
/// The size of the border round rect.
[Description("Set Slider's border round rect size")]
[Category("ColorSlider")]
[DefaultValue(typeof(Size), "8; 8")]
public Size BorderRoundRectSize
{
get { return _borderRoundRectSize; }
set
{
int h = value.Height, w = value.Width;
if (h <= 0) h = 1;
if (w <= 0) w = 1;
_borderRoundRectSize = new Size(w, h);
Invalidate();
}
}
private bool _drawSemitransparentThumb = true;
///
/// Gets or sets a value indicating whether to draw semitransparent thumb.
///
/// true if semitransparent thumb should be drawn; otherwise, false.
[Description("Set whether to draw semitransparent thumb")]
[Category("ColorSlider")]
[DefaultValue(true)]
public bool DrawSemitransparentThumb
{
get { return _drawSemitransparentThumb; }
set
{
_drawSemitransparentThumb = value;
Invalidate();
}
}
private Image _thumbImage = null;
//private Image _thumbImage = Properties.Resources.BTN_Thumb_Blue;
///
/// Gets or sets the Image used to render the thumb.
///
/// the thumb Image
[Description("Set to use a specific Image for the thumb")]
[Category("ColorSlider")]
[DefaultValue(null)]
public Image ThumbImage
{
get { return _thumbImage; }
set
{
if (value != null)
_thumbImage = value;
else
_thumbImage = null;
Invalidate();
}
}
#endregion
#region Appearance
private Orientation _barOrientation = Orientation.Horizontal;
///
/// Gets or sets the orientation of Slider.
///
/// The orientation.
[Description("Set Slider orientation")]
[Category("ColorSlider")]
[DefaultValue(Orientation.Horizontal)]
public Orientation Orientation
{
get { return _barOrientation; }
set
{
if (_barOrientation != value)
{
_barOrientation = value;
// Switch from horizontal to vertical (design mode)
// Comment these lines if problems in Run mode
if (this.DesignMode)
{
int temp = Width;
Width = Height;
Height = temp;
}
Invalidate();
}
}
}
private bool _drawFocusRectangle = false;
///
/// Gets or sets a value indicating whether to draw focus rectangle.
///
/// true if focus rectangle should be drawn; otherwise, false.
[Description("Set whether to draw focus rectangle")]
[Category("ColorSlider")]
[DefaultValue(false)]
public bool DrawFocusRectangle
{
get { return _drawFocusRectangle; }
set
{
_drawFocusRectangle = value;
Invalidate();
}
}
private bool _mouseEffects = true;
///
/// Gets or sets whether mouse entry and exit actions have impact on how control look.
///
/// true if mouse entry and exit actions have impact on how control look; otherwise, false.
[Description("Set whether mouse entry and exit actions have impact on how control look")]
[Category("ColorSlider")]
[DefaultValue(true)]
public bool MouseEffects
{
get { return _mouseEffects; }
set
{
_mouseEffects = value;
Invalidate();
}
}
#endregion
#region values
private int _trackerValue = 30;
///
/// Gets or sets the value of Slider.
///
/// The value.
/// exception thrown when value is outside appropriate range (min, max)
[Description("Set Slider value")]
[Category("ColorSlider")]
[DefaultValue(30)]
public int Value
{
get { return _trackerValue; }
set
{
if (value >= _minimum & value <= _maximum)
{
_trackerValue = value;
if (ValueChanged != null) ValueChanged(this, new EventArgs());
Invalidate();
}
else throw new ArgumentOutOfRangeException("Value is outside appropriate range (min, max)");
}
}
private int _minimum = 0;
///
/// Gets or sets the minimum value.
///
/// The minimum value.
/// exception thrown when minimal value is greather than maximal one
[Description("Set Slider minimal point")]
[Category("ColorSlider")]
[DefaultValue(0)]
public int Minimum
{
get { return _minimum; }
set
{
if (value < _maximum)
{
_minimum = value;
if (_trackerValue < _minimum)
{
_trackerValue = _minimum;
if (ValueChanged != null) ValueChanged(this, new EventArgs());
}
Invalidate();
}
else throw new ArgumentOutOfRangeException("Minimal value is greather than maximal one");
}
}
private int _maximum = 100;
///
/// Gets or sets the maximum value.
///
/// The maximum value.
/// exception thrown when maximal value is lower than minimal one
[Description("Set Slider maximal point")]
[Category("ColorSlider")]
[DefaultValue(100)]
public int Maximum
{
get { return _maximum; }
set
{
if (value > _minimum)
{
_maximum = value;
if (_trackerValue > _maximum)
{
_trackerValue = _maximum;
if (ValueChanged != null) ValueChanged(this, new EventArgs());
}
Invalidate();
}
//else throw new ArgumentOutOfRangeException("Maximal value is lower than minimal one");
}
}
private uint _smallChange = 1;
///
/// Gets or sets trackbar's small change. It affects how to behave when directional keys are pressed
///
/// The small change value.
[Description("Set trackbar's small change")]
[Category("ColorSlider")]
[DefaultValue(1)]
public uint SmallChange
{
get { return _smallChange; }
set { _smallChange = value; }
}
private uint _largeChange = 5;
///
/// Gets or sets trackbar's large change. It affects how to behave when PageUp/PageDown keys are pressed
///
/// The large change value.
[Description("Set trackbar's large change")]
[Category("ColorSlider")]
[DefaultValue(5)]
public uint LargeChange
{
get { return _largeChange; }
set { _largeChange = value; }
}
private int _mouseWheelBarPartitions = 10;
///
/// Gets or sets the mouse wheel bar partitions.
///
/// The mouse wheel bar partitions.
/// exception thrown when value isn't greather than zero
[Description("Set to how many parts is bar divided when using mouse wheel")]
[Category("ColorSlider")]
[DefaultValue(10)]
public int MouseWheelBarPartitions
{
get { return _mouseWheelBarPartitions; }
set
{
if (value > 0)
_mouseWheelBarPartitions = value;
else throw new ArgumentOutOfRangeException("MouseWheelBarPartitions has to be greather than zero");
}
}
#endregion
#region colors
private Color _thumbOuterColor = Color.White;
///
/// Gets or sets the thumb outer color.
///
/// The thumb outer color.
[Description("Sets Slider thumb outer color")]
[Category("ColorSlider")]
[DefaultValue(typeof(Color), "White")]
public Color ThumbOuterColor
{
get { return _thumbOuterColor; }
set
{
_thumbOuterColor = value;
Invalidate();
}
}
private Color _thumbInnerColor = Color.FromArgb(21, 56, 152);
///
/// Gets or sets the inner color of the thumb.
///
/// The inner color of the thumb.
[Description("Set Slider thumb inner color")]
[Category("ColorSlider")]
public Color ThumbInnerColor
{
get { return _thumbInnerColor; }
set
{
_thumbInnerColor = value;
Invalidate();
}
}
private Color _thumbPenColor = Color.FromArgb(21, 56, 152);
///
/// Gets or sets the color of the thumb pen.
///
/// The color of the thumb pen.
[Description("Set Slider thumb pen color")]
[Category("ColorSlider")]
public Color ThumbPenColor
{
get { return _thumbPenColor; }
set
{
_thumbPenColor = value;
Invalidate();
}
}
private Color _barInnerColor = Color.Black;
///
/// Gets or sets the inner color of the bar.
///
/// The inner color of the bar.
[Description("Set Slider bar inner color")]
[Category("ColorSlider")]
[DefaultValue(typeof(Color), "Black")]
public Color BarInnerColor
{
get { return _barInnerColor; }
set
{
_barInnerColor = value;
Invalidate();
}
}
private Color _elapsedPenColorTop = Color.FromArgb(95, 140, 180); // bleu clair
///
/// Gets or sets the top color of the Elapsed
///
[Description("Gets or sets the top color of the elapsed")]
[Category("ColorSlider")]
public Color ElapsedPenColorTop
{
get { return _elapsedPenColorTop; }
set
{
_elapsedPenColorTop = value;
Invalidate();
}
}
private Color _elapsedPenColorBottom = Color.FromArgb(99, 130, 208); // bleu très clair
///
/// Gets or sets the bottom color of the elapsed
///
[Description("Gets or sets the bottom color of the elapsed")]
[Category("ColorSlider")]
public Color ElapsedPenColorBottom
{
get { return _elapsedPenColorBottom; }
set
{
_elapsedPenColorBottom = value;
Invalidate();
}
}
private Color _barPenColorTop = Color.FromArgb(55, 60, 74); // gris foncé
///
/// Gets or sets the top color of the bar
///
[Description("Gets or sets the top color of the bar")]
[Category("ColorSlider")]
public Color BarPenColorTop
{
get { return _barPenColorTop; }
set
{
_barPenColorTop = value;
Invalidate();
}
}
private Color _barPenColorBottom = Color.FromArgb(87, 94, 110); // gris moyen
///
/// Gets or sets the bottom color of bar
///
[Description("Gets or sets the bottom color of the bar")]
[Category("ColorSlider")]
public Color BarPenColorBottom
{
get { return _barPenColorBottom; }
set
{
_barPenColorBottom = value;
Invalidate();
}
}
private Color _elapsedInnerColor = Color.FromArgb(21, 56, 152);
///
/// Gets or sets the inner color of the elapsed.
///
/// The inner color of the elapsed.
[Description("Set Slider's elapsed part inner color")]
[Category("ColorSlider")]
public Color ElapsedInnerColor
{
get { return _elapsedInnerColor; }
set
{
_elapsedInnerColor = value;
Invalidate();
}
}
private Color _tickColor = Color.White;
///
/// Gets or sets the color of the graduations
///
[Description("Color of graduations")]
[Category("ColorSlider")]
public Color TickColor
{
get { return _tickColor; }
set
{
if (value != _tickColor)
{
_tickColor = value;
Invalidate();
}
}
}
#endregion
#region divisions
// For ex: if values are multiples of 50,
// values = 0, 50, 100, 150 etc...
//set TickDivide to 50
// And ticks will be displayed as
// values = 0, 1, 2, 3 etc...
private float _tickDivide = 0;
[Description("Gets or sets a value used to divide the graduation")]
[Category("ColorSlider")]
public float TickDivide
{
get { return _tickDivide; }
set
{
_tickDivide = value;
Invalidate();
}
}
private float _tickAdd = 0;
[Description("Gets or sets a value added to the graduation")]
[Category("ColorSlider")]
public float TickAdd
{
get { return _tickAdd; }
set
{
_tickAdd = value;
Invalidate();
}
}
private TickStyle _tickStyle = TickStyle.TopLeft;
///
/// Gets or sets where to display the ticks (None, both top-left, bottom-right)
///
[Description("Gets or sets where to display the ticks")]
[Category("ColorSlider")]
[DefaultValue(TickStyle.TopLeft)]
public TickStyle TickStyle
{
get { return _tickStyle; }
set
{
_tickStyle = value;
Invalidate();
}
}
private int _scaleDivisions = 10;
///
/// How many divisions of maximum?
///
[Description("Set the number of intervals between minimum and maximum")]
[Category("ColorSlider")]
public int ScaleDivisions
{
get { return _scaleDivisions; }
set
{
if (value > 0)
{
_scaleDivisions = value;
}
//else throw new ArgumentOutOfRangeException("TickFreqency must be > 0 and < Maximum");
Invalidate();
}
}
private int _scaleSubDivisions = 5;
///
/// How many subdivisions for each division
///
[Description("Set the number of subdivisions between main divisions of graduation.")]
[Category("ColorSlider")]
public int ScaleSubDivisions
{
get { return _scaleSubDivisions; }
set
{
if (value > 0 && _scaleDivisions > 0 && (_maximum - _minimum) / ((value + 1) * _scaleDivisions) > 0)
{
_scaleSubDivisions = value;
}
//else throw new ArgumentOutOfRangeException("TickSubFreqency must be > 0 and < TickFrequency");
Invalidate();
}
}
private bool _showSmallScale = false;
///
/// Shows Small Scale marking.
///
[Description("Show or hide subdivisions of graduations")]
[Category("ColorSlider")]
public bool ShowSmallScale
{
get { return _showSmallScale; }
set
{
if (value == true)
{
if (_scaleDivisions > 0 && _scaleSubDivisions > 0 && (_maximum - _minimum) / ((_scaleSubDivisions + 1) * _scaleDivisions) > 0)
{
_showSmallScale = value;
Invalidate();
}
else
{
_showSmallScale = false;
}
}
else
{
_showSmallScale = value;
// need to redraw
Invalidate();
}
}
}
private bool _showDivisionsText = true;
///
/// Shows Small Scale marking.
///
[Description("Show or hide text value of graduations")]
[Category("ColorSlider")]
public bool ShowDivisionsText
{
get { return _showDivisionsText; }
set
{
_showDivisionsText = value;
Invalidate();
}
}
#endregion
#region Font
///
/// Get or Sets the Font of the Text being displayed.
///
[Bindable(true),
Browsable(true),
Category("ColorSlider"),
Description("Get or Sets the Font of the Text being displayed."),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
EditorBrowsable(EditorBrowsableState.Always)]
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
Invalidate();
OnFontChanged(EventArgs.Empty);
}
}
///
/// Get or Sets the Font of the Text being displayed.
///
[Bindable(true),
Browsable(true),
Category("ColorSlider"),
Description("Get or Sets the Color of the Text being displayed."),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
EditorBrowsable(EditorBrowsableState.Always)]
public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
Invalidate();
OnForeColorChanged(EventArgs.Empty);
}
}
#endregion
#endregion
#region Color schemas
//define own color schemas
private Color[,] aColorSchema = new Color[,]
{
{
Color.White, // thumb outer
Color.FromArgb(21, 56, 152), // thumb inner
Color.FromArgb(21, 56, 152), // thumb pen color
Color.Black, // bar inner
Color.FromArgb(95, 140, 180), // slider elapsed top
Color.FromArgb(99, 130, 208), // slider elapsed bottom
Color.FromArgb(55, 60, 74), // slider remain top
Color.FromArgb(87, 94, 110), // slider remain bottom
Color.FromArgb(21, 56, 152) // elapsed interieur centre
},
{
Color.White, // thumb outer
Color.Red, // thumb inner
Color.Red, // thumb pen color
Color.Black, // bar inner
Color.LightCoral, // slider elapsed top
Color.Salmon, // slider elapsed bottom
Color.FromArgb(55, 60, 74), // slider remain top
Color.FromArgb(87, 94, 110), // slider remain bottom
Color.Red // gauche interieur centre
},
{
Color.White, // thumb outer
Color.Green, // thumb inner
Color.Green, // thumb pen color
Color.Black, // bar inner
Color.SpringGreen, // slider elapsed top
Color.LightGreen, // slider elapsed bottom
Color.FromArgb(55, 60, 74), // slider remain top
Color.FromArgb(87, 94, 110), // slider remain bottom
Color.Green // gauche interieur centre
},
};
public enum ColorSchemas
{
BlueColors,
RedColors,
GreenColors
}
private ColorSchemas colorSchema = ColorSchemas.BlueColors;
///
/// Sets color schema. Color generalization / fast color changing. Has no effect when slider colors are changed manually after schema was applied.
///
/// New color schema value
[Description("Set Slider color schema. Has no effect when slider colors are changed manually after schema was applied.")]
[Category("ColorSlider")]
[DefaultValue(typeof(ColorSchemas), "BlueColors")]
public ColorSchemas ColorSchema
{
get { return colorSchema; }
set
{
colorSchema = value;
byte sn = (byte)value;
_thumbOuterColor = aColorSchema[sn, 0];
_thumbInnerColor = aColorSchema[sn, 1];
_thumbPenColor = aColorSchema[sn, 2];
_barInnerColor = aColorSchema[sn, 3];
_elapsedPenColorTop = aColorSchema[sn, 4];
_elapsedPenColorBottom = aColorSchema[sn, 5];
_barPenColorTop = aColorSchema[sn, 6];
_barPenColorBottom = aColorSchema[sn, 7];
_elapsedInnerColor = aColorSchema[sn, 8];
Invalidate();
}
}
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The minimum value.
/// The maximum value.
/// The current value.
public TrackbarKeyEditor(int min, int max, int value)
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw | ControlStyles.Selectable |
ControlStyles.SupportsTransparentBackColor | ControlStyles.UserMouse |
ControlStyles.UserPaint, true);
// Default backcolor
BackColor = Color.FromArgb(70, 77, 95);
ForeColor = Color.White;
// Font
//this.Font = new Font("Tahoma", 6.75f);
this.Font = new Font("Microsoft Sans Serif", 6f);
Minimum = min;
Maximum = max;
Value = value;
}
///
/// Initializes a new instance of the class.
///
public TrackbarKeyEditor() : this(0, 100, 30) { }
#endregion
#region Paint
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnPaint(PaintEventArgs e)
{
if (!Enabled)
{
Color[] desaturatedColors = DesaturateColors(_thumbOuterColor, _thumbInnerColor, _thumbPenColor,
_barInnerColor,
_elapsedPenColorTop, _elapsedPenColorBottom,
_barPenColorTop, _barPenColorBottom,
_elapsedInnerColor);
DrawColorSlider(e,
desaturatedColors[0], desaturatedColors[1], desaturatedColors[2],
desaturatedColors[3],
desaturatedColors[4], desaturatedColors[5],
desaturatedColors[6], desaturatedColors[7],
desaturatedColors[8]);
}
else
{
if (_mouseEffects && mouseInRegion)
{
Color[] lightenedColors = LightenColors(_thumbOuterColor, _thumbInnerColor, _thumbPenColor,
_barInnerColor,
_elapsedPenColorTop, _elapsedPenColorBottom,
_barPenColorTop, _barPenColorBottom,
_elapsedInnerColor);
DrawColorSlider(e,
lightenedColors[0], lightenedColors[1], lightenedColors[2],
lightenedColors[3],
lightenedColors[4], lightenedColors[5],
lightenedColors[6], lightenedColors[7],
lightenedColors[8]);
}
else
{
DrawColorSlider(e,
_thumbOuterColor, _thumbInnerColor, _thumbPenColor,
_barInnerColor,
_elapsedPenColorTop, _elapsedPenColorBottom,
_barPenColorTop, _barPenColorBottom,
_elapsedInnerColor);
}
}
}
///
/// Draws the colorslider control using passed colors.
///
/// The instance containing the event data.
/// The thumb outer color paint.
/// The thumb inner color paint.
/// The thumb pen color paint.
/// The bar inner color paint.
/// The bar pen color paint.
/// The elapsed inner color paint.
private void DrawColorSlider(PaintEventArgs e,
Color thumbOuterColorPaint, Color thumbInnerColorPaint, Color thumbPenColorPaint,
Color barInnerColorPaint,
Color ElapsedTopPenColorPaint, Color ElapsedBottomPenColorPaint,
Color barTopPenColorPaint, Color barBottomPenColorPaint,
Color elapsedInnerColorPaint)
{
try
{
//set up thumbRect approprietly
if (_barOrientation == Orientation.Horizontal)
{
#region horizontal
if (_thumbImage != null)
{
int TrackX = (((_trackerValue - _minimum) * (ClientRectangle.Width - _thumbImage.Width)) / (_maximum - _minimum));
thumbRect = new Rectangle(TrackX, ClientRectangle.Height / 2 - _thumbImage.Height / 2, _thumbImage.Width, _thumbImage.Height);
for (int i = 0; i < keyFrameThumbs.Count; i++)
{
int Frame = (((keyFrameThumbs[i].Frame - _minimum) * (ClientRectangle.Width - _thumbImage.Width)) / (_maximum - _minimum));
keyFrameThumbs[i].Rectangle = new Rectangle(Frame, keyFrameThumbs[i].Rectangle.Y, keyFrameThumbs[i].Rectangle.Size.Width, keyFrameThumbs[i].Rectangle.Size.Height);
}
}
else
{
int TrackX = (((_trackerValue - _minimum) * (ClientRectangle.Width - _thumbSize.Width)) / (_maximum - _minimum));
thumbRect = new Rectangle(TrackX, 0, _thumbSize.Width, ClientRectangle.Height);
for (int i = 0; i < keyFrameThumbs.Count; i++)
{
int thumbWidth = keyFrameThumbs[i].Rectangle.Size.Width;
int thumbHeight = keyFrameThumbs[i].Rectangle.Size.Height;
int Frame = (((keyFrameThumbs[i].Frame - _minimum) * (ClientRectangle.Width - _thumbSize.Width)) / (_maximum - _minimum));
if (keyFrameThumbs[i].bitmap != null)
{
// thumbWidth = keyFrameThumbs[i].bitmap.Width;
// thumbHeight = keyFrameThumbs[i].bitmap.Height;
}
keyFrameThumbs[i].Rectangle = new Rectangle(Frame - thumbWidth / 2, keyFrameThumbs[i].Rectangle.Y, thumbWidth, thumbHeight);
}
}
#endregion
}
else
{
#region vertical
if (_thumbImage != null)
{
int TrackY = (((_maximum - (_trackerValue)) * (ClientRectangle.Height - _thumbImage.Height)) / (_maximum - _minimum));
thumbRect = new Rectangle(ClientRectangle.Width / 2 - _thumbImage.Width / 2, TrackY, _thumbImage.Width, _thumbImage.Height);
}
else
{
int TrackY = (((_maximum - (_trackerValue)) * (ClientRectangle.Height - _thumbSize.Height)) / (_maximum - _minimum));
thumbRect = new Rectangle(ClientRectangle.X + ClientRectangle.Width / 2 - _thumbSize.Width / 2, TrackY, _thumbSize.Width, _thumbSize.Height);
}
#endregion
}
//adjust drawing rects
barRect = ClientRectangle;
// TODO : make barRect rectangle smaller than Control rectangle
// barRect = new Rectangle(ClientRectangle.X + 5, ClientRectangle.Y + 5, ClientRectangle.Width - 10, ClientRectangle.Height - 10);
thumbHalfRect = thumbRect;
LinearGradientMode gradientOrientation;
if (_barOrientation == Orientation.Horizontal)
{
#region horizontal
barRect.Inflate(-1, -barRect.Height / 3);
barHalfRect = barRect;
barHalfRect.Height /= 2;
gradientOrientation = LinearGradientMode.Vertical;
thumbHalfRect.Height /= 2;
elapsedRect = barRect;
elapsedRect.Width = thumbRect.Left + _thumbSize.Width / 2;
#endregion
}
else
{
#region vertical
barRect.Inflate(-barRect.Width / 3, -1);
barHalfRect = barRect;
barHalfRect.Width /= 2;
gradientOrientation = LinearGradientMode.Vertical;
thumbHalfRect.Width /= 2;
elapsedRect = barRect;
elapsedRect.Height = barRect.Height - (thumbRect.Top + ThumbSize.Height / 2);
elapsedRect.Y = 1 + thumbRect.Top + ThumbSize.Height / 2;
#endregion
}
List keyThumbPaths = new List();
for (int i = 0; i < keyFrameThumbs.Count; i++)
{
//get thumb shape path
GraphicsPath keyedThumbPath;
if (_thumbCustomShape == null)
keyedThumbPath = CreateRoundRectPath(keyFrameThumbs[i].Rectangle, _thumbRoundRectSize);
else
{
keyedThumbPath = _thumbCustomShape;
Matrix m = new Matrix();
m.Translate(keyFrameThumbs[i].Rectangle.Left - keyedThumbPath.GetBounds().Left, keyFrameThumbs[i].Rectangle.Top - keyedThumbPath.GetBounds().Top);
keyedThumbPath.Transform(m);
}
keyThumbPaths.Add(keyedThumbPath);
}
//get thumb shape path
GraphicsPath thumbPath = CreateRoundRectPath(thumbRect, _thumbRoundRectSize);
/* if (_thumbCustomShape == null)
thumbPath = CreateRoundRectPath(thumbRect, _thumbRoundRectSize);
else
{
thumbPath = _thumbCustomShape;
Matrix m = new Matrix();
m.Translate(thumbRect.Left - thumbPath.GetBounds().Left, thumbRect.Top - thumbPath.GetBounds().Top);
thumbPath.Transform(m);
}*/
//draw bar
#region draw inner bar
// inner bar is a single line
// draw the line on the whole lenght of the control
if (_barOrientation == Orientation.Horizontal)
{
e.Graphics.DrawLine(new Pen(barInnerColorPaint, 1f), barRect.X, barRect.Y + barRect.Height / 2, barRect.X + barRect.Width, barRect.Y + barRect.Height / 2);
}
else
{
e.Graphics.DrawLine(new Pen(barInnerColorPaint, 1f), barRect.X + barRect.Width / 2, barRect.Y, barRect.X + barRect.Width / 2, barRect.Y + barRect.Height);
}
#endregion
#region draw elapsed bar
//draw elapsed inner bar (single line too)
if (_barOrientation == Orientation.Horizontal)
{
e.Graphics.DrawLine(new Pen(elapsedInnerColorPaint, 1f), barRect.X, barRect.Y + barRect.Height / 2, barRect.X + elapsedRect.Width, barRect.Y + barRect.Height / 2);
}
else
{
e.Graphics.DrawLine(new Pen(elapsedInnerColorPaint, 1f), barRect.X + barRect.Width / 2, barRect.Y + (barRect.Height - elapsedRect.Height), barRect.X + barRect.Width / 2, barRect.Y + barRect.Height);
}
#endregion draw elapsed bar
#region draw external contours
//draw external bar band
// 2 lines: top and bottom
if (_barOrientation == Orientation.Horizontal)
{
#region horizontal
// Elapsed top
e.Graphics.DrawLine(new Pen(ElapsedTopPenColorPaint, 1f), barRect.X, barRect.Y - 1 + barRect.Height / 2, barRect.X + elapsedRect.Width, barRect.Y - 1 + barRect.Height / 2);
// Elapsed bottom
e.Graphics.DrawLine(new Pen(ElapsedBottomPenColorPaint, 1f), barRect.X, barRect.Y + 1 + barRect.Height / 2, barRect.X + elapsedRect.Width, barRect.Y + 1 + barRect.Height / 2);
// Remain top
e.Graphics.DrawLine(new Pen(barTopPenColorPaint, 1f), barRect.X + elapsedRect.Width, barRect.Y - 1 + barRect.Height / 2, barRect.X + barRect.Width, barRect.Y - 1 + barRect.Height / 2);
// Remain bottom
e.Graphics.DrawLine(new Pen(barBottomPenColorPaint, 1f), barRect.X + elapsedRect.Width, barRect.Y + 1 + barRect.Height / 2, barRect.X + barRect.Width, barRect.Y + 1 + barRect.Height / 2);
// Left vertical (dark)
e.Graphics.DrawLine(new Pen(barTopPenColorPaint, 1f), barRect.X, barRect.Y - 1 + barRect.Height / 2, barRect.X, barRect.Y + barRect.Height / 2 + 1);
// Right vertical (light)
e.Graphics.DrawLine(new Pen(barBottomPenColorPaint, 1f), barRect.X + barRect.Width, barRect.Y - 1 + barRect.Height / 2, barRect.X + barRect.Width, barRect.Y + 1 + barRect.Height / 2);
#endregion
}
else
{
#region vertical
// Elapsed top
e.Graphics.DrawLine(new Pen(ElapsedTopPenColorPaint, 1f), barRect.X - 1 + barRect.Width / 2, barRect.Y + (barRect.Height - elapsedRect.Height), barRect.X - 1 + barRect.Width / 2, barRect.Y + barRect.Height);
// Elapsed bottom
e.Graphics.DrawLine(new Pen(ElapsedBottomPenColorPaint, 1f), barRect.X + 1 + barRect.Width / 2, barRect.Y + (barRect.Height - elapsedRect.Height), barRect.X + 1 + barRect.Width / 2, barRect.Y + barRect.Height);
// Remain top
e.Graphics.DrawLine(new Pen(barTopPenColorPaint, 1f), barRect.X - 1 + barRect.Width / 2, barRect.Y, barRect.X - 1 + barRect.Width / 2, barRect.Y + barRect.Height - elapsedRect.Height);
// Remain bottom
e.Graphics.DrawLine(new Pen(barBottomPenColorPaint, 1f), barRect.X + 1 + barRect.Width / 2, barRect.Y, barRect.X + 1 + barRect.Width / 2, barRect.Y + barRect.Height - elapsedRect.Height);
// top horizontal (dark)
e.Graphics.DrawLine(new Pen(barTopPenColorPaint, 1f), barRect.X - 1 + barRect.Width / 2, barRect.Y, barRect.X + 1 + barRect.Width / 2, barRect.Y);
// bottom horizontal (light)
e.Graphics.DrawLine(new Pen(barBottomPenColorPaint, 1f), barRect.X - 1 + barRect.Width / 2, barRect.Y + barRect.Height, barRect.X + 1 + barRect.Width / 2, barRect.Y + barRect.Height);
#endregion
}
#endregion draw contours
#region draw thumb
//draw thumb
Color newthumbOuterColorPaint = thumbOuterColorPaint, newthumbInnerColorPaint = thumbInnerColorPaint;
if (Capture && _drawSemitransparentThumb)
{
newthumbOuterColorPaint = Color.FromArgb(175, thumbOuterColorPaint);
newthumbInnerColorPaint = Color.FromArgb(175, thumbInnerColorPaint);
}
List lgbKeyedThumbs = new List();
LinearGradientBrush lgbThumb;
if (_barOrientation == Orientation.Horizontal)
{
lgbThumb = new LinearGradientBrush(thumbRect, newthumbOuterColorPaint, newthumbInnerColorPaint, gradientOrientation);
for (int i = 0; i < keyFrameThumbs.Count; i++)
lgbKeyedThumbs.Add(new LinearGradientBrush(thumbRect, keyFrameThumbs[i].Color, keyFrameThumbs[i].Color, gradientOrientation));
}
else
{
lgbThumb = new LinearGradientBrush(thumbHalfRect, newthumbOuterColorPaint, newthumbInnerColorPaint, gradientOrientation);
}
using (lgbThumb)
{
lgbThumb.WrapMode = WrapMode.TileFlipXY;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(lgbThumb, thumbPath);
//draw thumb band
Color newThumbPenColor = thumbPenColorPaint;
if (_mouseEffects && (Capture || mouseInThumbRegion))
newThumbPenColor = ControlPaint.Dark(newThumbPenColor);
using (Pen thumbPen = new Pen(newThumbPenColor))
{
if (_thumbImage != null)
{
Bitmap bmp = new Bitmap(_thumbImage);
bmp.MakeTransparent(Color.FromArgb(255, 0, 255));
Rectangle srceRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
e.Graphics.DrawImage(bmp, thumbRect, srceRect, GraphicsUnit.Pixel);
bmp.Dispose();
}
else
{
e.Graphics.DrawPath(thumbPen, thumbPath);
}
}
}
for (int i = 0; i < lgbKeyedThumbs.Count; i++)
{
using (lgbKeyedThumbs[i])
{
lgbKeyedThumbs[i].WrapMode = WrapMode.TileFlipXY;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.FillPath(lgbKeyedThumbs[i], keyThumbPaths[i]);
//draw thumb band
Color newThumbPenColor = keyFrameThumbs[i].Color;
if (_mouseEffects && (Capture || mouseInThumbRegion))
newThumbPenColor = ControlPaint.Dark(newThumbPenColor);
using (Pen thumbPen = new Pen(newThumbPenColor))
{
if (keyFrameThumbs[i].bitmap != null)
{
Bitmap bmp = new Bitmap(keyFrameThumbs[i].bitmap);
bmp.MakeTransparent(Color.FromArgb(255, 0, 255));
Rectangle srceRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
e.Graphics.DrawImage(bmp, keyFrameThumbs[i].Rectangle, srceRect, GraphicsUnit.Pixel);
bmp.Dispose();
}
else
{
e.Graphics.DrawPath(thumbPen, keyThumbPaths[i]);
}
}
}
}
#endregion draw thumb
#region draw focusing rectangle
//draw focusing rectangle
if (Focused & _drawFocusRectangle)
using (Pen p = new Pen(Color.FromArgb(200, ElapsedTopPenColorPaint)))
{
p.DashStyle = DashStyle.Dot;
Rectangle r = ClientRectangle;
r.Width -= 2;
r.Height--;
r.X++;
using (GraphicsPath gpBorder = CreateRoundRectPath(r, _borderRoundRectSize))
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawPath(p, gpBorder);
}
}
#endregion draw focusing rectangle
#region draw ticks
// Draw the ticks (main divisions, subdivisions and text)
if (_tickStyle != TickStyle.None)
{
int x1, x2, y1, y2 = 0;
int nbticks = 1 + _scaleDivisions * (_scaleSubDivisions + 1);
int interval = 0;
int start = 0;
int W = 0;
float rulerValue = 0;
// Calculate width W to draw graduations
// Remove the width of the thumb (half thumb at each end)
// in order that when the thumb is at minimum position or maximum position,
// the graduation coincide with the middle of the thumb
if (_barOrientation == Orientation.Horizontal)
{
start = thumbRect.Width / 2;
W = barRect.Width - thumbRect.Width;
rulerValue = (float)_minimum;
}
else
{
start = thumbRect.Height / 2;
W = barRect.Height - thumbRect.Height;
rulerValue = (float)_maximum;
}
// pen for ticks
// TODO: color for subdivision different?
Pen penTickL = new Pen(_tickColor, 1f);
Pen penTickS = new Pen(_tickColor, 1f);
int idx = 0;
int scaleL = 5; // division lenght
int scaleS = 3; // subdivision length
// strings graduations
// TODO: color for Text different?
float tx = 0;
float ty = 0;
//float fSize = (float)(7F);
int startDiv = 0;
//Color _scaleColor = Color.White;
Color _scaleColor = ForeColor;
SolidBrush br = new SolidBrush(_scaleColor);
// Caluculate max size of text
String str = String.Format("{0,0:D}", _maximum);
//Font font = new Font(this.Font.FontFamily, fSize);
Font font = this.Font;
SizeF maxsize = e.Graphics.MeasureString(str, font);
float lineLeftX, lineRightX = 0;
lineLeftX = ClientRectangle.X + maxsize.Width / 2;
lineRightX = ClientRectangle.X + ClientRectangle.Width - maxsize.Width / 2;
Pen penGrid = new Pen(Color.FromArgb(70, 80, 80, 80), 1f);
//Draw grid
for (int i = 0; i <= _maximum; i++)
{
interval = i * W / (nbticks - 1);
x1 = start + barRect.X + interval;
y1 = start + 0 + interval;
e.Graphics.DrawLine(penGrid, x1, 0, x1, ClientSize.Height);
e.Graphics.DrawLine(penGrid, 0, y1, ClientSize.Width, y1);
}
for (int i = 0; i <= _scaleDivisions; i++)
{
// Calculate current text size
double val = Math.Round(rulerValue);
// apply a transformation to the ticks displayed
if (_tickDivide != 0)
val = val / _tickDivide;
if (_tickAdd != 0)
val = val + _tickAdd;
str = String.Format("{0,0:D}", (int)val);
SizeF size = e.Graphics.MeasureString(str, font);
// HORIZONTAL
if (_barOrientation == Orientation.Horizontal)
{
#region horizontal
// Draw string graduations
if (_showDivisionsText)
{
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
tx = (start + barRect.X + interval) - (float)(size.Width * 0.5);
ty = ClientRectangle.Y;
e.Graphics.DrawString(str, font, br, tx, ty);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
tx = (start + barRect.X + interval) - (float)(size.Width * 0.5);
ty = ClientRectangle.Y + ClientRectangle.Height - (size.Height) + 3;
e.Graphics.DrawString(str, font, br, tx, ty);
}
startDiv = (int)size.Height;
}
// draw main ticks
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
x1 = start + barRect.X + interval;
y1 = ClientRectangle.Y + startDiv;
x2 = start + barRect.X + interval;
y2 = ClientRectangle.Y + startDiv + scaleL;
e.Graphics.DrawLine(penTickL, x1, y1, x2, y2);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
x1 = start + barRect.X + interval;
y1 = ClientRectangle.Y + ClientRectangle.Height - startDiv;
x2 = start + barRect.X + interval;
y2 = ClientRectangle.Y + ClientRectangle.Height - scaleL - startDiv;
e.Graphics.DrawLine(penTickL, x1, y1, x2, y2);
}
rulerValue += (float)((_maximum - _minimum) / (_scaleDivisions));
// Draw subdivisions
if (i < _scaleDivisions)
{
for (int j = 0; j <= _scaleSubDivisions; j++)
{
idx++;
interval = idx * W / (nbticks - 1);
if (_showSmallScale)
{
// Horizontal
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
x1 = start + barRect.X + interval;
y1 = ClientRectangle.Y + startDiv;
x2 = start + barRect.X + interval;
y2 = ClientRectangle.Y + startDiv + scaleS;
e.Graphics.DrawLine(penTickS, x1, y1, x2, y2);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
x1 = start + barRect.X + interval;
y1 = ClientRectangle.Y + ClientRectangle.Height - startDiv;
x2 = start + barRect.X + interval;
y2 = ClientRectangle.Y + ClientRectangle.Height - scaleS - startDiv;
e.Graphics.DrawLine(penTickS, x1, y1, x2, y2);
}
}
}
}
#endregion
}
else
{
#region vertical
// Draw string graduations
if (_showDivisionsText)
{
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
tx = lineLeftX - size.Width / 2;
ty = start + barRect.Y + interval - (float)(size.Height * 0.5);
e.Graphics.DrawString(str, font, br, tx, ty);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
tx = lineRightX - size.Width / 2;
ty = start + barRect.Y + interval - (float)(size.Height * 0.5);
e.Graphics.DrawString(str, font, br, tx, ty);
}
startDiv = (int)maxsize.Width + 3;
}
// draw main ticks
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
x1 = ClientRectangle.X + startDiv;
y1 = start + barRect.Y + interval;
x2 = ClientRectangle.X + scaleL + startDiv;
y2 = start + barRect.Y + interval;
e.Graphics.DrawLine(penTickL, x1, y1, x2, y2);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
x1 = ClientRectangle.X + ClientRectangle.Width - startDiv;
y1 = start + barRect.Y + interval;
x2 = ClientRectangle.X + ClientRectangle.Width - scaleL - startDiv;
y2 = start + barRect.Y + interval;
e.Graphics.DrawLine(penTickL, x1, y1, x2, y2);
}
rulerValue -= (float)((_maximum - _minimum) / (_scaleDivisions));
// draw subdivisions
if (i < _scaleDivisions)
{
for (int j = 0; j <= _scaleSubDivisions; j++)
{
idx++;
interval = idx * W / (nbticks - 1);
if (_showSmallScale)
{
if (_tickStyle == TickStyle.TopLeft || _tickStyle == TickStyle.Both)
{
x1 = ClientRectangle.X + startDiv;
y1 = start + barRect.Y + interval;
x2 = ClientRectangle.X + scaleS + startDiv;
y2 = start + barRect.Y + interval;
e.Graphics.DrawLine(penTickS, x1, y1, x2, y2);
}
if (_tickStyle == TickStyle.BottomRight || _tickStyle == TickStyle.Both)
{
x1 = ClientRectangle.X + ClientRectangle.Width - startDiv;
y1 = start + barRect.Y + interval;
x2 = ClientRectangle.X + ClientRectangle.Width - scaleS - startDiv;
y2 = start + barRect.Y + interval;
e.Graphics.DrawLine(penTickS, x1, y1, x2, y2);
}
}
}
}
#endregion
}
}
}
#endregion
}
catch (Exception Err)
{
Console.WriteLine("DrawBackGround Error in " + Name + ":" + Err.Message);
}
finally
{
}
}
#endregion
#region Overided events
private bool mouseInRegion = false;
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
Invalidate();
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
mouseInRegion = true;
Invalidate();
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
mouseInRegion = false;
mouseInThumbRegion = false;
Invalidate();
}
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
Capture = true;
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.ThumbTrack, _trackerValue));
if (ValueChanged != null) ValueChanged(this, new EventArgs());
OnMouseMove(e);
}
}
private bool mouseInThumbRegion = false;
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
mouseInThumbRegion = IsPointInRect(e.Location, thumbRect);
if (Capture & e.Button == MouseButtons.Left)
{
ScrollEventType set = ScrollEventType.ThumbPosition;
Point pt = e.Location;
int p = _barOrientation == Orientation.Horizontal ? pt.X : pt.Y;
int margin = _thumbSize.Height >> 1;
p -= margin;
float coef = (float)(_maximum - _minimum) /
(float)
((_barOrientation == Orientation.Horizontal ? ClientSize.Width : ClientSize.Height) - 2 * margin);
_trackerValue = _barOrientation == Orientation.Horizontal ? (int)(p * coef + _minimum) : (_maximum - (int)(p * coef));
if (_trackerValue <= _minimum)
{
_trackerValue = _minimum;
set = ScrollEventType.First;
}
else if (_trackerValue >= _maximum)
{
_trackerValue = _maximum;
set = ScrollEventType.Last;
}
if (Scroll != null) Scroll(this, new ScrollEventArgs(set, _trackerValue));
if (ValueChanged != null) ValueChanged(this, new EventArgs());
}
Invalidate();
}
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Capture = false;
mouseInThumbRegion = IsPointInRect(e.Location, thumbRect);
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.EndScroll, _trackerValue));
if (ValueChanged != null) ValueChanged(this, new EventArgs());
Invalidate();
}
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
if (mouseInRegion)
{
int v = e.Delta / 120 * (_maximum - _minimum) / _mouseWheelBarPartitions;
SetProperValue(Value + v);
// Avoid to send MouseWheel event to the parent container
((HandledMouseEventArgs)e).Handled = true;
}
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
Invalidate();
}
///
/// Raises the event.
///
/// An that contains the event data.
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
Invalidate();
}
///
/// Raises the event.
///
/// A that contains the event data.
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
switch (e.KeyCode)
{
case Keys.Down:
case Keys.Left:
SetProperValue(Value - (int)_smallChange);
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallDecrement, Value));
break;
case Keys.Up:
case Keys.Right:
SetProperValue(Value + (int)_smallChange);
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallIncrement, Value));
break;
case Keys.Home:
Value = _minimum;
break;
case Keys.End:
Value = _maximum;
break;
case Keys.PageDown:
SetProperValue(Value - (int)_largeChange);
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeDecrement, Value));
break;
case Keys.PageUp:
SetProperValue(Value + (int)_largeChange);
if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, Value));
break;
}
if (Scroll != null && Value == _minimum) Scroll(this, new ScrollEventArgs(ScrollEventType.First, Value));
if (Scroll != null && Value == _maximum) Scroll(this, new ScrollEventArgs(ScrollEventType.Last, Value));
Point pt = PointToClient(Cursor.Position);
OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, pt.X, pt.Y, 0));
}
///
/// Processes a dialog key.
///
/// One of the values that represents the key to process.
///
/// true if the key was processed by the control; otherwise, false.
///
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Tab | ModifierKeys == Keys.Shift)
return base.ProcessDialogKey(keyData);
else
{
OnKeyDown(new KeyEventArgs(keyData));
return true;
}
}
#endregion
#region Help routines
///
/// Creates the round rect path.
///
/// The rectangle on which graphics path will be spanned.
/// The size of rounded rectangle edges.
///
public static GraphicsPath CreateRoundRectPath(Rectangle rect, Size size)
{
GraphicsPath gp = new GraphicsPath();
gp.AddLine(rect.Left + size.Width / 2, rect.Top, rect.Right - size.Width / 2, rect.Top);
gp.AddArc(rect.Right - size.Width, rect.Top, size.Width, size.Height, 270, 90);
gp.AddLine(rect.Right, rect.Top + size.Height / 2, rect.Right, rect.Bottom - size.Width / 2);
gp.AddArc(rect.Right - size.Width, rect.Bottom - size.Height, size.Width, size.Height, 0, 90);
gp.AddLine(rect.Right - size.Width / 2, rect.Bottom, rect.Left + size.Width / 2, rect.Bottom);
gp.AddArc(rect.Left, rect.Bottom - size.Height, size.Width, size.Height, 90, 90);
gp.AddLine(rect.Left, rect.Bottom - size.Height / 2, rect.Left, rect.Top + size.Height / 2);
gp.AddArc(rect.Left, rect.Top, size.Width, size.Height, 180, 90);
return gp;
}
///
/// Desaturates colors from given array.
///
/// The colors to be desaturated.
///
public static Color[] DesaturateColors(params Color[] colorsToDesaturate)
{
Color[] colorsToReturn = new Color[colorsToDesaturate.Length];
for (int i = 0; i < colorsToDesaturate.Length; i++)
{
//use NTSC weighted avarage
int gray =
(int)(colorsToDesaturate[i].R * 0.3 + colorsToDesaturate[i].G * 0.6 + colorsToDesaturate[i].B * 0.1);
colorsToReturn[i] = Color.FromArgb(-0x010101 * (255 - gray) - 1);
}
return colorsToReturn;
}
///
/// Lightens colors from given array.
///
/// The colors to lighten.
///
public static Color[] LightenColors(params Color[] colorsToLighten)
{
Color[] colorsToReturn = new Color[colorsToLighten.Length];
for (int i = 0; i < colorsToLighten.Length; i++)
{
colorsToReturn[i] = ControlPaint.Light(colorsToLighten[i]);
}
return colorsToReturn;
}
///
/// Sets the trackbar value so that it wont exceed allowed range.
///
/// The value.
private void SetProperValue(int val)
{
if (val < _minimum) Value = _minimum;
else if (val > _maximum) Value = _maximum;
else Value = val;
}
///
/// Determines whether rectangle contains given point.
///
/// The point to test.
/// The base rectangle.
///
/// true if rectangle contains given point; otherwise, false.
///
private static bool IsPointInRect(Point pt, Rectangle rect)
{
if (pt.X > rect.Left & pt.X < rect.Right & pt.Y > rect.Top & pt.Y < rect.Bottom)
return true;
else return false;
}
#endregion
}
}