using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using Microsoft.Win32;
namespace Unclassified.UI
{
///
[Designer(typeof(InfoLabelDesigner))]
[DefaultEvent("Click")]
public class InfoLabel : UserControl
{
#region Private fields
private bool useBorder = false;
private Color borderColor;
private Pen borderColorPen;
private Brush backColorBrush;
private Color hoverBackColor;
private Color hoverBorderColor;
private Pen hoverBorderColorPen;
private Brush hoverBackColorBrush;
private Color hoverForeColor;
private Brush hoverForeColorBrush;
private bool hovering = false;
private bool supportHovering = false;
private ContextMenu contextMenu = null;
private ContextMenuStrip contextMenuStrip = null;
#endregion Private fields
#region Constructors
public InfoLabel()
{
InitializeComponent();
BackColor = SystemColors.Info;
ForeColor = SystemColors.InfoText;
BorderColor = SystemColors.ControlDark;
HoverBackColor = SystemColors.Highlight;
HoverForeColor = SystemColors.HighlightText;
HoverBorderColor = SystemColors.ControlDark;
}
#endregion Constructors
#region Designer stuff
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label label1;
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label1 = new System.Windows.Forms.Label();
this.flowLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize) (this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel1.BackColor = System.Drawing.Color.Transparent;
this.flowLayoutPanel1.Controls.Add(this.pictureBox1);
this.flowLayoutPanel1.Controls.Add(this.label1);
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Padding = new System.Windows.Forms.Padding(3);
this.flowLayoutPanel1.Size = new System.Drawing.Size(279, 34);
this.flowLayoutPanel1.TabIndex = 0;
this.flowLayoutPanel1.MouseLeave += new System.EventHandler(this.flowLayoutPanel1_MouseLeave);
this.flowLayoutPanel1.Click += new System.EventHandler(this.flowLayoutPanel1_Click);
this.flowLayoutPanel1.Resize += new System.EventHandler(this.flowLayoutPanel1_Resize);
this.flowLayoutPanel1.MouseEnter += new System.EventHandler(this.flowLayoutPanel1_MouseEnter);
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.flowLayoutPanel1.SetFlowBreak(this.pictureBox1, true);
this.pictureBox1.Location = new System.Drawing.Point(3, 3);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(1, 0, 2, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(16, 16);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Visible = false;
this.pictureBox1.MouseLeave += new System.EventHandler(this.flowLayoutPanel1_MouseLeave);
this.pictureBox1.Click += new System.EventHandler(this.flowLayoutPanel1_Click);
this.pictureBox1.MouseEnter += new System.EventHandler(this.flowLayoutPanel1_MouseEnter);
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Location = new System.Drawing.Point(23, 4);
this.label1.Margin = new System.Windows.Forms.Padding(0, 1, 0, 1);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(247, 26);
this.label1.TabIndex = 1;
this.label1.Text = "label1";
this.label1.UseMnemonic = false;
this.label1.MouseLeave += new System.EventHandler(this.flowLayoutPanel1_MouseLeave);
this.label1.Click += new System.EventHandler(this.flowLayoutPanel1_Click);
this.label1.MouseEnter += new System.EventHandler(this.flowLayoutPanel1_MouseEnter);
//
// InfoLabel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowLayoutPanel1);
this.DoubleBuffered = true;
this.Name = "InfoLabel";
this.Size = new System.Drawing.Size(279, 80);
this.Enter += new System.EventHandler(this.InfoLabel_Enter);
this.Leave += new System.EventHandler(this.InfoLabel_Leave);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.InfoLabel_KeyDown);
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize) (this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion Designer stuff
#region Old properties
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
backColorBrush = new SolidBrush(value);
}
}
[Browsable(false)]
public override Image BackgroundImage
{
get
{
return base.BackgroundImage;
}
set
{
base.BackgroundImage = null;
}
}
[Browsable(false)]
public override ImageLayout BackgroundImageLayout
{
get
{
return base.BackgroundImageLayout;
}
set
{
base.BackgroundImageLayout = ImageLayout.None;
}
}
[Browsable(false)]
public new BorderStyle BorderStyle
{
get
{
return BorderStyle.None;
}
}
public override AnchorStyles Anchor
{
get
{
return base.Anchor;
}
set
{
if ((value & AnchorStyles.Top) != 0 && (value & AnchorStyles.Bottom) != 0)
throw new ArgumentException();
base.Anchor = value;
}
}
[Browsable(false)]
public override bool AutoScroll
{
get
{
return base.AutoScroll;
}
set
{
base.AutoScroll = false;
}
}
[Browsable(false)]
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = false;
}
}
public override DockStyle Dock
{
get
{
return base.Dock;
}
set
{
if (value == DockStyle.Fill || value == DockStyle.Left || value == DockStyle.Right)
throw new ArgumentException();
base.Dock = value;
}
}
// This must be named different from "Text" because the designer won't
// store that property persistently and reset it every time the project
// is rebuilt.
//[Category("Appearance")]
//[Browsable(false)]
//public string Text2
//{
// get
// {
// return label1.Text;
// }
// set
// {
// label1.Text = value;
// }
//}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get
{
return label1.Text;
}
set
{
label1.Text = value;
}
}
public override ContextMenu ContextMenu
{
get
{
return contextMenu;
}
set
{
contextMenu = value;
}
}
public override ContextMenuStrip ContextMenuStrip
{
get
{
return contextMenuStrip;
}
set
{
contextMenuStrip = value;
}
}
#endregion Old properties
#region New properties
[Category("Appearance")]
public Color BorderColor
{
get
{
return borderColor;
}
set
{
borderColor = value;
borderColorPen = new Pen(borderColor);
Invalidate();
}
}
[Category("Appearance")]
public Color HoverBorderColor
{
get
{
return hoverBorderColor;
}
set
{
hoverBorderColor = value;
hoverBorderColorPen = new Pen(hoverBorderColor);
Invalidate();
}
}
[Category("Appearance")]
public bool UseBorder
{
get
{
return useBorder;
}
set
{
useBorder = value;
flowLayoutPanel1.Padding = new Padding(useBorder ? 3 : 2);
Invalidate();
}
}
[Category("Appearance")]
public Color HoverBackColor
{
get
{
return hoverBackColor;
}
set
{
hoverBackColor = value;
hoverBackColorBrush = new SolidBrush(value);
Invalidate();
}
}
[Category("Appearance")]
public Color HoverForeColor
{
get
{
return hoverForeColor;
}
set
{
hoverForeColor = value;
hoverForeColorBrush = new SolidBrush(value);
Invalidate();
}
}
[Category("Appearance")]
public Image IconImage
{
get
{
return pictureBox1.Image;
}
set
{
pictureBox1.Image = value;
pictureBox1.Visible = value != null;
}
}
[Category("Behavior")]
public bool SupportHovering
{
get
{
return supportHovering;
}
set
{
supportHovering = value;
UpdateHovering();
Invalidate();
}
}
#endregion New properties
#region New event handlers
protected override void OnSizeChanged(EventArgs e)
{
Invalidate();
base.OnSizeChanged(e);
}
private void flowLayoutPanel1_Resize(object sender, EventArgs e)
{
UpdateSize();
}
private void flowLayoutPanel1_MouseEnter(object sender, EventArgs e)
{
hovering = true;
UpdateHovering();
Invalidate();
}
private void flowLayoutPanel1_MouseLeave(object sender, EventArgs e)
{
hovering = false;
UpdateHovering();
Invalidate();
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
if (useBorder)
{
if (supportHovering && hovering)
{
e.Graphics.FillRectangle(hoverBackColorBrush, 1, 1, Width - 2, Height - 2);
e.Graphics.DrawRectangle(hoverBorderColorPen, 0, 0, Width - 1, Height - 1);
}
else
{
//e.Graphics.FillRectangle(backColorBrush, 1, 1, Width - 2, Height - 2);
e.Graphics.DrawRectangle(borderColorPen, 0, 0, Width - 1, Height - 1);
}
}
else
{
if (supportHovering && hovering)
{
e.Graphics.FillRectangle(hoverBackColorBrush, 0, 0, Width, Height);
}
else
{
//e.Graphics.FillRectangle(backColorBrush, 0, 0, Width, Height);
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (Focused || FindForm() != null && FindForm().ActiveControl == this) // Focused alone doesn't work when re-activating the window
{
e.Graphics.DrawRectangle(new Pen(new HatchBrush(HatchStyle.Percent50, label1.ForeColor, Color.Empty)), 0, 0, Width - 1, Height - 1);
}
}
#endregion New event handlers
#region Other private methods
private void UpdateSize()
{
int oldHeight = Height;
Height = flowLayoutPanel1.Height;
if (Height != oldHeight)
Invalidate();
}
private void UpdateHovering()
{
if (supportHovering && hovering)
{
label1.ForeColor = HoverForeColor;
Cursor = HandCursor;
}
else
{
label1.ForeColor = Color.Empty;
Cursor = Cursors.Default;
}
}
#endregion Other private methods
#region Public events
public new event EventHandler Click;
private void flowLayoutPanel1_Click(object sender, EventArgs e)
{
if (ContextMenu != null)
{
ContextMenu.Show(this, new Point(0, Height - (useBorder ? 1 : 0)));
}
else if (ContextMenuStrip != null)
{
ContextMenuStrip.Show(this, new Point(0, Height - (useBorder ? 1 : 0)));
}
else
{
if (Click != null) Click(this, EventArgs.Empty);
}
}
private void InfoLabel_Enter(object sender, EventArgs e)
{
Invalidate();
}
private void InfoLabel_Leave(object sender, EventArgs e)
{
Invalidate();
}
private void InfoLabel_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Enter || e.KeyCode == Keys.Space) && !e.Alt && !e.Control && !e.Shift)
{
flowLayoutPanel1_Click(this, EventArgs.Empty);
e.Handled = true;
e.SuppressKeyPress = true;
}
}
#endregion Public events
#region WinAPI stuff
// This comes from class Unclassified.WinApi
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LoadCursorFromFile(string path);
///
/// Gets the system's hand mouse cursor, used for hyperlinks.
/// The .NET framework only gives its internal cursor but not the one that the user has set in their profile.
///
private Cursor HandCursor
{
get
{
RegistryKey cursorsKey = Registry.CurrentUser.OpenSubKey(@"Control Panel\Cursors");
if (cursorsKey != null)
{
object o = cursorsKey.GetValue("Hand");
if (o is string)
{
IntPtr cursorHandle = WinApi.LoadCursorFromFile((string) o);
return new Cursor(cursorHandle);
}
}
return Cursors.Hand;
}
}
}
#endregion WinAPI stuff
}
public class InfoLabelDesigner : ControlDesigner
{
public override SelectionRules SelectionRules
{
get
{
return base.SelectionRules & ~(SelectionRules.TopSizeable | SelectionRules.BottomSizeable);
}
}
}
}