v1.2
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* Created/modified in 2011 by Simon Baer
|
||||
*
|
||||
* Based on the Code Project article by Nicolas Wälti:
|
||||
* http://www.codeproject.com/KB/cpp/PopupNotifier.aspx
|
||||
*
|
||||
* Licensed under the Code Project Open License (CPOL).
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Tulpep.NotificationWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the form of the actual notification window.
|
||||
/// </summary>
|
||||
internal class PopupNotifierForm : System.Windows.Forms.Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that is raised when the text is clicked.
|
||||
/// </summary>
|
||||
public event EventHandler LinkClick;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when the notification window is manually closed.
|
||||
/// </summary>
|
||||
public event EventHandler CloseClick;
|
||||
|
||||
internal event EventHandler ContextMenuOpened;
|
||||
internal event EventHandler ContextMenuClosed;
|
||||
|
||||
private bool mouseOnClose = false;
|
||||
private bool mouseOnLink = false;
|
||||
private bool mouseOnOptions = false;
|
||||
private int heightOfTitle;
|
||||
|
||||
#region GDI objects
|
||||
|
||||
private bool gdiInitialized = false;
|
||||
private Rectangle rcBody;
|
||||
private Rectangle rcHeader;
|
||||
private Rectangle rcForm;
|
||||
private LinearGradientBrush brushBody;
|
||||
private LinearGradientBrush brushHeader;
|
||||
private Brush brushButtonHover;
|
||||
private Pen penButtonBorder;
|
||||
private Pen penContent;
|
||||
private Pen penBorder;
|
||||
private Brush brushForeColor;
|
||||
private Brush brushLinkHover;
|
||||
private Brush brushContent;
|
||||
private Brush brushTitle;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance.
|
||||
/// </summary>
|
||||
/// <param name="parent">PopupNotifier</param>
|
||||
public PopupNotifierForm(PopupNotifier parent)
|
||||
{
|
||||
Parent = parent;
|
||||
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
||||
this.SetStyle(ControlStyles.ResizeRedraw, true);
|
||||
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
this.ShowInTaskbar = false;
|
||||
|
||||
this.VisibleChanged += new EventHandler(PopupNotifierForm_VisibleChanged);
|
||||
this.MouseMove += new MouseEventHandler(PopupNotifierForm_MouseMove);
|
||||
this.MouseUp += new MouseEventHandler(PopupNotifierForm_MouseUp);
|
||||
this.Paint += new PaintEventHandler(PopupNotifierForm_Paint);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The form is shown/hidden.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void PopupNotifierForm_VisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (this.Visible)
|
||||
{
|
||||
mouseOnClose = false;
|
||||
mouseOnLink = false;
|
||||
mouseOnOptions = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used in design mode.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// PopupNotifierForm
|
||||
//
|
||||
this.ClientSize = new System.Drawing.Size(392, 66);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Name = "PopupNotifierForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent control.
|
||||
/// </summary>
|
||||
public new PopupNotifier Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Add two values but do not return a value greater than 255.
|
||||
/// </summary>
|
||||
/// <param name="input">first value</param>
|
||||
/// <param name="add">value to add</param>
|
||||
/// <returns>sum of both values</returns>
|
||||
private int AddValueMax255(int input, int add)
|
||||
{
|
||||
return (input + add < 256) ? input + add : 255;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract two values but do not returns a value below 0.
|
||||
/// </summary>
|
||||
/// <param name="input">first value</param>
|
||||
/// <param name="ded">value to subtract</param>
|
||||
/// <returns>first value minus second value</returns>
|
||||
private int DedValueMin0(int input, int ded)
|
||||
{
|
||||
return (input - ded > 0) ? input - ded : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color which is darker than the given color.
|
||||
/// </summary>
|
||||
/// <param name="color">Color</param>
|
||||
/// <returns>darker color</returns>
|
||||
private Color GetDarkerColor(Color color)
|
||||
{
|
||||
return System.Drawing.Color.FromArgb(255, DedValueMin0((int)color.R, Parent.GradientPower), DedValueMin0((int)color.G, Parent.GradientPower), DedValueMin0((int)color.B, Parent.GradientPower));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color which is lighter than the given color.
|
||||
/// </summary>
|
||||
/// <param name="color">Color</param>
|
||||
/// <returns>lighter color</returns>
|
||||
private Color GetLighterColor(Color color)
|
||||
{
|
||||
return System.Drawing.Color.FromArgb(255, AddValueMax255((int)color.R, Parent.GradientPower), AddValueMax255((int)color.G, Parent.GradientPower), AddValueMax255((int)color.B, Parent.GradientPower));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rectangle of the content text.
|
||||
/// </summary>
|
||||
private RectangleF RectContentText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Parent.Image != null)
|
||||
{
|
||||
return new RectangleF(
|
||||
Parent.ImagePadding.Left + Parent.ImageSize.Width + Parent.ImagePadding.Right + Parent.ContentPadding.Left,
|
||||
Parent.HeaderHeight + Parent.TitlePadding.Top + heightOfTitle + Parent.TitlePadding.Bottom + Parent.ContentPadding.Top,
|
||||
this.Width - Parent.ImagePadding.Left - Parent.ImageSize.Width - Parent.ImagePadding.Right - Parent.ContentPadding.Left - Parent.ContentPadding.Right - 16 - 5,
|
||||
this.Height - Parent.HeaderHeight - Parent.TitlePadding.Top - heightOfTitle - Parent.TitlePadding.Bottom - Parent.ContentPadding.Top - Parent.ContentPadding.Bottom - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new RectangleF(
|
||||
Parent.ContentPadding.Left,
|
||||
Parent.HeaderHeight + Parent.TitlePadding.Top + heightOfTitle + Parent.TitlePadding.Bottom + Parent.ContentPadding.Top,
|
||||
this.Width - Parent.ContentPadding.Left - Parent.ContentPadding.Right - 16 - 5,
|
||||
this.Height - Parent.HeaderHeight - Parent.TitlePadding.Top - heightOfTitle - Parent.TitlePadding.Bottom - Parent.ContentPadding.Top - Parent.ContentPadding.Bottom - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets the rectangle of the close button.
|
||||
/// </summary>
|
||||
private Rectangle RectClose
|
||||
{
|
||||
get { return new Rectangle(this.Width - 5 - 16, Parent.HeaderHeight + 3, 16, 16); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rectangle of the options button.
|
||||
/// </summary>
|
||||
private Rectangle RectOptions
|
||||
{
|
||||
get { return new Rectangle(this.Width - 5 - 16, Parent.HeaderHeight + 3 + 16 + 5, 16, 16); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update form to display hover styles when the mouse moves over the notification form.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void PopupNotifierForm_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Parent.ShowCloseButton)
|
||||
{
|
||||
mouseOnClose = RectClose.Contains(e.X, e.Y);
|
||||
}
|
||||
if (Parent.ShowOptionsButton)
|
||||
{
|
||||
mouseOnOptions = RectOptions.Contains(e.X, e.Y);
|
||||
}
|
||||
mouseOnLink = RectContentText.Contains(e.X, e.Y);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A mouse button has been released, check if something has been clicked.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void PopupNotifierForm_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == System.Windows.Forms.MouseButtons.Left)
|
||||
{
|
||||
if (RectClose.Contains(e.X, e.Y) && (CloseClick != null))
|
||||
{
|
||||
CloseClick(this, EventArgs.Empty);
|
||||
}
|
||||
if (RectContentText.Contains(e.X, e.Y) && (LinkClick != null))
|
||||
{
|
||||
LinkClick(this, EventArgs.Empty);
|
||||
}
|
||||
if (RectOptions.Contains(e.X, e.Y) && (Parent.OptionsMenu != null))
|
||||
{
|
||||
if (ContextMenuOpened != null)
|
||||
{
|
||||
ContextMenuOpened(this, EventArgs.Empty);
|
||||
}
|
||||
Parent.OptionsMenu.Show(this, new Point(RectOptions.Right - Parent.OptionsMenu.Width, RectOptions.Bottom));
|
||||
Parent.OptionsMenu.Closed += new ToolStripDropDownClosedEventHandler(OptionsMenu_Closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The options popup menu has been closed.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OptionsMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
||||
{
|
||||
Parent.OptionsMenu.Closed -= new ToolStripDropDownClosedEventHandler(OptionsMenu_Closed);
|
||||
|
||||
if (ContextMenuClosed != null)
|
||||
{
|
||||
ContextMenuClosed(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create all GDI objects used to paint the form.
|
||||
/// </summary>
|
||||
private void AllocateGDIObjects()
|
||||
{
|
||||
rcBody = new Rectangle(0, 0, this.Width, this.Height);
|
||||
rcHeader = new Rectangle(0, 0, this.Width, Parent.HeaderHeight);
|
||||
rcForm = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
|
||||
|
||||
brushBody = new LinearGradientBrush(rcBody, Parent.BodyColor, GetLighterColor(Parent.BodyColor), LinearGradientMode.Vertical);
|
||||
brushHeader = new LinearGradientBrush(rcHeader, Parent.HeaderColor, GetDarkerColor(Parent.HeaderColor), LinearGradientMode.Vertical);
|
||||
brushButtonHover = new SolidBrush(Parent.ButtonHoverColor);
|
||||
penButtonBorder = new Pen(Parent.ButtonBorderColor);
|
||||
penContent = new Pen(Parent.ContentColor, 2);
|
||||
penBorder = new Pen(Parent.BorderColor);
|
||||
brushForeColor = new SolidBrush(ForeColor);
|
||||
brushLinkHover = new SolidBrush(Parent.ContentHoverColor);
|
||||
brushContent = new SolidBrush(Parent.ContentColor);
|
||||
brushTitle = new SolidBrush(Parent.TitleColor);
|
||||
|
||||
gdiInitialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free all GDI objects.
|
||||
/// </summary>
|
||||
private void DisposeGDIObjects()
|
||||
{
|
||||
if (gdiInitialized)
|
||||
{
|
||||
brushBody.Dispose();
|
||||
brushHeader.Dispose();
|
||||
brushButtonHover.Dispose();
|
||||
penButtonBorder.Dispose();
|
||||
penContent.Dispose();
|
||||
penBorder.Dispose();
|
||||
brushForeColor.Dispose();
|
||||
brushLinkHover.Dispose();
|
||||
brushContent.Dispose();
|
||||
brushTitle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the notification form.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void PopupNotifierForm_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
if (!gdiInitialized)
|
||||
{
|
||||
AllocateGDIObjects();
|
||||
}
|
||||
|
||||
// draw window
|
||||
e.Graphics.FillRectangle(brushBody, rcBody);
|
||||
e.Graphics.FillRectangle(brushHeader, rcHeader);
|
||||
e.Graphics.DrawRectangle(penBorder, rcForm);
|
||||
if (Parent.ShowGrip)
|
||||
{
|
||||
e.Graphics.DrawImage(Properties.Resources.Grip, (int)((this.Width - Properties.Resources.Grip.Width) / 2), (int)((Parent.HeaderHeight - 3) / 2));
|
||||
}
|
||||
if (Parent.ShowCloseButton)
|
||||
{
|
||||
if (mouseOnClose)
|
||||
{
|
||||
e.Graphics.FillRectangle(brushButtonHover, RectClose);
|
||||
e.Graphics.DrawRectangle(penButtonBorder, RectClose);
|
||||
}
|
||||
e.Graphics.DrawLine(penContent, RectClose.Left + 4, RectClose.Top + 4, RectClose.Right - 4, RectClose.Bottom - 4);
|
||||
e.Graphics.DrawLine(penContent, RectClose.Left + 4, RectClose.Bottom - 4, RectClose.Right - 4, RectClose.Top + 4);
|
||||
}
|
||||
if (Parent.ShowOptionsButton)
|
||||
{
|
||||
if (mouseOnOptions)
|
||||
{
|
||||
e.Graphics.FillRectangle(brushButtonHover, RectOptions);
|
||||
e.Graphics.DrawRectangle(penButtonBorder, RectOptions);
|
||||
}
|
||||
e.Graphics.FillPolygon(brushForeColor, new Point[] { new Point(RectOptions.Left + 4, RectOptions.Top + 6), new Point(RectOptions.Left + 12, RectOptions.Top + 6), new Point(RectOptions.Left + 8, RectOptions.Top + 4 + 6) });
|
||||
}
|
||||
|
||||
// draw icon
|
||||
if (Parent.Image != null)
|
||||
{
|
||||
e.Graphics.DrawImage(Parent.Image, Parent.ImagePadding.Left, Parent.HeaderHeight + Parent.ImagePadding.Top, Parent.ImageSize.Width, Parent.ImageSize.Height);
|
||||
}
|
||||
|
||||
|
||||
if (Parent.IsRightToLeft)
|
||||
{
|
||||
heightOfTitle = (int)e.Graphics.MeasureString("A", Parent.TitleFont).Height;
|
||||
|
||||
// the value 30 is because of x close icon
|
||||
int titleX2 = this.Width - 30;// Parent.TitlePadding.Right;
|
||||
|
||||
// draw title right to left
|
||||
StringFormat headerFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft);
|
||||
e.Graphics.DrawString(Parent.TitleText, Parent.TitleFont, brushTitle, titleX2, Parent.HeaderHeight + Parent.TitlePadding.Top, headerFormat);
|
||||
|
||||
// draw content text, optionally with a bold part
|
||||
this.Cursor = mouseOnLink ? Cursors.Hand : Cursors.Default;
|
||||
Brush brushText = mouseOnLink ? brushLinkHover : brushContent;
|
||||
|
||||
// draw content right to left
|
||||
StringFormat contentFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft);
|
||||
e.Graphics.DrawString(Parent.ContentText, Parent.ContentFont, brushText, RectContentText, contentFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate height of title
|
||||
heightOfTitle = (int)e.Graphics.MeasureString("A", Parent.TitleFont).Height;
|
||||
int titleX = Parent.TitlePadding.Left;
|
||||
if (Parent.Image != null)
|
||||
titleX += Parent.ImagePadding.Left + Parent.ImageSize.Width + Parent.ImagePadding.Right;
|
||||
e.Graphics.DrawString(Parent.TitleText, Parent.TitleFont, brushTitle, titleX, Parent.HeaderHeight + Parent.TitlePadding.Top);
|
||||
// draw content text, optionally with a bold part
|
||||
this.Cursor = mouseOnLink ? Cursors.Hand : Cursors.Default;
|
||||
Brush brushText = mouseOnLink ? brushLinkHover : brushContent;
|
||||
e.Graphics.DrawString(Parent.ContentText, Parent.ContentFont, brushText, RectContentText);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose GDI objects.
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
DisposeGDIObjects();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user