/// /// Copyright © 2003-2008 JetBrains s.r.o. /// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder). /// using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; namespace JetBrains.UI.Components.ImageListButton { /// /// A simple button which draws one of four images from the image list depending on its /// state. /// public class ImageListButton : UserControl { private ImageList _imageList; private int _normalImageIndex = -1; private int _hotImageIndex = -1; private int _disabledImageIndex = -1; private int _pressedImageIndex = -1; private bool _pressed = false; private bool _hot = false; /// /// Tooltip of this button. /// protected ToolTip _tooltip; public ImageListButton() { SetStyle( ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.AllPaintingInWmPaint | ControlStyles.CacheText | ControlStyles.UserPaint | ControlStyles.FixedHeight | ControlStyles.FixedWidth, true ); SetStyle( ControlStyles.StandardClick | ControlStyles.Selectable | ControlStyles.ResizeRedraw, false ); _tooltip = new ToolTip(); } [DefaultValue( null )] public ImageList ImageList { get { return _imageList; } set { if (_imageList != value) { _imageList = value; Invalidate(); } } } [DefaultValue( -1 )] public int NormalImageIndex { get { return _normalImageIndex; } set { if (_normalImageIndex != value) { _normalImageIndex = value; Invalidate(); } } } [DefaultValue( -1 )] public int HotImageIndex { get { return _hotImageIndex; } set { _hotImageIndex = value; } } [DefaultValue( -1 )] public int DisabledImageIndex { get { return _disabledImageIndex; } set { if (_disabledImageIndex != value) { _disabledImageIndex = value; if (!Enabled) Invalidate(); } } } public int PressedImageIndex { get { return _pressedImageIndex; } set { _pressedImageIndex = value; } } protected override void OnEnabledChanged( EventArgs e ) { base.OnEnabledChanged( e ); Invalidate(); } protected override void OnPaint( PaintEventArgs e ) { // Background if(BackColor != Color.Transparent) { // If the parent is capable of providing a background brush, use it IBackgroundBrushProvider bbp = Parent as IBackgroundBrushProvider; Brush brush = bbp != null ? bbp.GetBackgroundBrush(this) : new SolidBrush(BackColor); using(brush) e.Graphics.FillRectangle( brush, ClientRectangle ); } // Foreground (icon) int imageIndex = GetCurrentImageIndex(); if (_imageList != null && imageIndex >= 0 && imageIndex < _imageList.Images.Count) _imageList.Draw( e.Graphics, 0, 0, imageIndex ); } private int GetCurrentImageIndex() { if (!Enabled && _disabledImageIndex >= 0) return _disabledImageIndex; if (_pressed && _pressedImageIndex >= 0) return _pressedImageIndex; if (_hot && _hotImageIndex >= 0) return _hotImageIndex; return _normalImageIndex; } protected override void OnMouseDown( MouseEventArgs e ) { base.OnMouseDown( e ); if (e.Button == MouseButtons.Left) { _pressed = true; Invalidate(); } } protected override void OnMouseUp( MouseEventArgs e ) { base.OnMouseUp( e ); if (e.Button == MouseButtons.Left) { bool wasPressed = _pressed; _pressed = false; Invalidate(); if (wasPressed) OnClick( EventArgs.Empty ); } } protected override void OnMouseMove( MouseEventArgs e ) { base.OnMouseMove( e ); if (e.Button == MouseButtons.Left) { bool newPressed = (ClientRectangle.Contains( e.X, e.Y )); if (_pressed != newPressed) { _pressed = newPressed; Invalidate(); } } } protected override void OnMouseEnter( EventArgs e ) { base.OnMouseEnter( e ); _hot = true; if (_hotImageIndex >= 0 && Enabled) Invalidate(); } protected override void OnMouseLeave( EventArgs e ) { base.OnMouseLeave( e ); _hot = false; if (_hotImageIndex >= 0 && Enabled) Invalidate(); } /// /// Tooltip text of this control. An empty string to cancel the tooltip. /// [DefaultValue("")] public string ToolTip { get { return _tooltip.GetToolTip( this ); } set { if(value == null) throw new ArgumentNullException(); _tooltip.SetToolTip( this, value ); } } /// /// Adds an icon to the buttons image list and assigns it to a specific state of the button. /// public void AddIcon(Icon icon, ButtonState state) { // Create & init the image list using the first image's properties, if there's no imagelist currently if(_imageList == null) { _imageList = new ImageList(); _imageList.ImageSize = icon.Size; _imageList.ColorDepth = ColorDepth.Depth32Bit; Size = icon.Size; // Resize the button to fit the icons } // Add the new image and store its index int nIndex = _imageList.Images.Count; _imageList.Images.Add(icon); // Assign to the state appropriate (this also invalidates) switch(state) { case ButtonState.Normal: NormalImageIndex = nIndex; break; case ButtonState.Hot: HotImageIndex = nIndex; break; case ButtonState.Disabled: DisabledImageIndex = nIndex; break; case ButtonState.Pushed: PressedImageIndex = nIndex; break; } } /// /// Possible states of this button. /// public enum ButtonState { /// /// The normal button state. The button is not hovered with mouse nor is in a checked/pushed state. /// Normal, /// /// The button is hovered by the mouse, but not pushed. /// Hot, /// /// The button is disabled. /// Disabled, /// /// The button is pushed. /// Pushed } } /// /// An interface for the control that provides its background brush for painting the child controls' background. /// public interface IBackgroundBrushProvider { /// /// Requests the parent for a background brush for painting the child control . /// If the brush is a gradient brush, its rectangle must be adjusted accordingly for the background to fit seamlessly. /// /// A control that sends the brush request. Must be an immediate child of the requestee, its indirect child, or the same control. /// A brush that should be disposed after use. Brush GetBackgroundBrush(Control sender); } }