mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-20 15:36:03 +01:00
358 lines
14 KiB
C#
358 lines
14 KiB
C#
|
/* Copyright (c) Citrix Systems Inc.
|
|||
|
* All rights reserved.
|
|||
|
*
|
|||
|
* Redistribution and use in source and binary forms,
|
|||
|
* with or without modification, are permitted provided
|
|||
|
* that the following conditions are met:
|
|||
|
*
|
|||
|
* * Redistributions of source code must retain the above
|
|||
|
* copyright notice, this list of conditions and the
|
|||
|
* following disclaimer.
|
|||
|
* * Redistributions in binary form must reproduce the above
|
|||
|
* copyright notice, this list of conditions and the
|
|||
|
* following disclaimer in the documentation and/or other
|
|||
|
* materials provided with the distribution.
|
|||
|
*
|
|||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|||
|
* SUCH DAMAGE.
|
|||
|
*/
|
|||
|
|
|||
|
using System;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.Drawing;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
namespace XenAdmin.Controls
|
|||
|
{
|
|||
|
public partial class SectionHeaderLabel : UserControl
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Vertical Alignment enumeration. This doesn;t appear in .NET until 4.0
|
|||
|
/// </summary>
|
|||
|
public enum VerticalAlignment
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Align to the Top of the control
|
|||
|
/// </summary>
|
|||
|
Top,
|
|||
|
/// <summary>
|
|||
|
/// Align to the vertical center of the control
|
|||
|
/// </summary>
|
|||
|
Middle,
|
|||
|
/// <summary>
|
|||
|
/// Align to the Bottom of the control
|
|||
|
/// </summary>
|
|||
|
Bottom
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Horizontal alignment of the control text
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public HorizontalAlignment LabelHorizontalAlignment { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Text to display
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public string LabelText { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Padding around the text
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public Padding LabelPadding { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Vertical alignment of the header line
|
|||
|
/// </summary>
|
|||
|
public VerticalAlignment LineLocation { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Color of the header line
|
|||
|
/// </summary>
|
|||
|
public Color LineColor { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Padding around the header line
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public Padding LinePadding { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Use mnemonic for setting focus on a control
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public bool UseMnemonic { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The control on which to set focus when mnemonic key is pressed
|
|||
|
/// </summary>
|
|||
|
[Localizable(true)]
|
|||
|
public Control FocusControl { get; set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Public constructor
|
|||
|
/// </summary>
|
|||
|
public SectionHeaderLabel()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
|
|||
|
this.LineColor = Color.Black;
|
|||
|
SetStyle(ControlStyles.UserPaint |
|
|||
|
ControlStyles.AllPaintingInWmPaint |
|
|||
|
ControlStyles.OptimizedDoubleBuffer |
|
|||
|
ControlStyles.ResizeRedraw, true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Custom OnPoint method
|
|||
|
/// </summary>
|
|||
|
/// <param name="e">PaintEventArgs object</param>
|
|||
|
protected override void OnPaint(PaintEventArgs e)
|
|||
|
{
|
|||
|
DrawLine(e.Graphics);
|
|||
|
DrawLabel(e.Graphics);
|
|||
|
Size baseHeight = new Size(0, this.Padding.Vertical +
|
|||
|
(this.LinePadding.Vertical + 1) +
|
|||
|
this.LabelPadding.Vertical +
|
|||
|
(int)e.Graphics.MeasureString(this.LabelText, this.Font).Height);
|
|||
|
this.MinimumSize = baseHeight;
|
|||
|
base.OnPaint(e);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Handle mnemonic events to set focus to the FocusControl
|
|||
|
/// </summary>
|
|||
|
/// <param name="charCode"></param>
|
|||
|
/// <returns></returns>
|
|||
|
protected override bool ProcessMnemonic(char charCode)
|
|||
|
{
|
|||
|
if (this.UseMnemonic && Control.IsMnemonic(charCode, this.LabelText) && (Control.ModifierKeys == Keys.Alt) && null != this.FocusControl)
|
|||
|
{
|
|||
|
this.FocusControl.Focus();
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Draws the text label of the control
|
|||
|
/// </summary>
|
|||
|
/// <param name="graphics">Current graphics drawing object</param>
|
|||
|
private void DrawLabel(Graphics graphics)
|
|||
|
{
|
|||
|
StringFormat sf = new StringFormat();
|
|||
|
if (this.UseMnemonic)
|
|||
|
{
|
|||
|
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
|
|||
|
if (!this.ShowKeyboardCues)
|
|||
|
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide;
|
|||
|
}
|
|||
|
else
|
|||
|
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
|
|||
|
sf.FormatFlags = StringFormatFlags.NoWrap;
|
|||
|
|
|||
|
//Make sure our brush is disposed
|
|||
|
using (SolidBrush brush = new SolidBrush(this.ForeColor))
|
|||
|
{
|
|||
|
PointF pointF = GetTextPointF(graphics);
|
|||
|
//Draw the actual text
|
|||
|
graphics.DrawString(this.LabelText, this.Font, brush, pointF, sf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Draw the header line
|
|||
|
/// </summary>
|
|||
|
/// <param name="graphics">Current graphics drawing object</param>
|
|||
|
private void DrawLine(Graphics graphics)
|
|||
|
{
|
|||
|
//These are used a lot in here...
|
|||
|
SizeF textSizeF = graphics.MeasureString(this.LabelText, this.Font);
|
|||
|
float lineY = GetLineVerticalLocation();
|
|||
|
|
|||
|
//Make sure our pen is disposed
|
|||
|
using (Pen pen = new Pen(this.LineColor))
|
|||
|
{
|
|||
|
if (LineLocation == VerticalAlignment.Middle)
|
|||
|
{
|
|||
|
switch (LabelHorizontalAlignment)
|
|||
|
{
|
|||
|
case HorizontalAlignment.Left:
|
|||
|
{
|
|||
|
//Draw a line from the right end of the text to the right end of the control
|
|||
|
DrawLeftLine(graphics, textSizeF, lineY, pen);
|
|||
|
break;
|
|||
|
}
|
|||
|
case HorizontalAlignment.Right:
|
|||
|
{
|
|||
|
//Draw a line from the left end of the control to the left end of the text
|
|||
|
DrawRightLine(graphics, textSizeF, lineY, pen);
|
|||
|
break;
|
|||
|
}
|
|||
|
case HorizontalAlignment.Center:
|
|||
|
{
|
|||
|
//Draw a line from the left of the control, to the left of the label,
|
|||
|
// then from the right of the label to the right of the control
|
|||
|
DrawLeftLine(graphics, textSizeF, lineY, pen);
|
|||
|
DrawRightLine(graphics, textSizeF, lineY, pen);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
float startX = (float)this.Padding.Left + //Control left padding
|
|||
|
(float)LinePadding.Left; //Line left padding
|
|||
|
float endX = (float)this.Width - //Control width
|
|||
|
(float)this.Padding.Right - //Control right padding
|
|||
|
(float)this.LinePadding.Right; //Line right padding
|
|||
|
graphics.DrawLine(pen, startX, lineY, endX, lineY);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void DrawRightLine(Graphics graphics, SizeF textSizeF, float lineY, Pen pen)
|
|||
|
{
|
|||
|
float startX = (float)this.Padding.Left + //Control left padding
|
|||
|
(float)LinePadding.Left; //Line left padding
|
|||
|
float endX = (float)this.Width - //Control width
|
|||
|
(float)this.Padding.Right - //Control right padding
|
|||
|
(float)this.LinePadding.Right - //Line right padding
|
|||
|
(float)this.LabelPadding.Horizontal - //Label horizontal padding
|
|||
|
textSizeF.Width; //Width of the label text
|
|||
|
graphics.DrawLine(pen, startX, lineY, endX, lineY);
|
|||
|
}
|
|||
|
|
|||
|
private void DrawLeftLine(Graphics graphics, SizeF textSizeF, float lineY, Pen pen)
|
|||
|
{
|
|||
|
float startX = (float)this.Padding.Left + //Control left padding
|
|||
|
(float)LabelPadding.Horizontal + //Label left+right padding
|
|||
|
(float)LinePadding.Left + //Line left padding
|
|||
|
textSizeF.Width; //Width of the label text
|
|||
|
float endX = (float)this.Width - //Control width
|
|||
|
(float)this.Padding.Right - //Control right padding
|
|||
|
(float)this.LinePadding.Right; //Line right padding
|
|||
|
graphics.DrawLine(pen, startX, lineY, endX, lineY);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Determines the left point of the line
|
|||
|
/// </summary>
|
|||
|
/// <param name="graphics">Current graphics drawing object</param>
|
|||
|
/// <returns>Returns the left PointF</returns>
|
|||
|
private PointF GetLeftLinePoint(Graphics graphics)
|
|||
|
{
|
|||
|
PointF pointF = new PointF();
|
|||
|
|
|||
|
pointF.X = this.Padding.Left + this.LinePadding.Left;
|
|||
|
|
|||
|
pointF.Y = GetLineVerticalLocation();
|
|||
|
|
|||
|
return pointF;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Determines the right point of the line
|
|||
|
/// </summary>
|
|||
|
/// <param name="graphics">Current graphics drawing object</param>
|
|||
|
/// <returns>Returns the right PointF</returns>
|
|||
|
private PointF GetRightLinePoint(Graphics graphics)
|
|||
|
{
|
|||
|
PointF pointF = new PointF();
|
|||
|
|
|||
|
pointF.X = this.Width - this.Padding.Right - this.LinePadding.Right;
|
|||
|
|
|||
|
pointF.Y = GetLineVerticalLocation();
|
|||
|
|
|||
|
return pointF;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Determines the vertical location of the line
|
|||
|
/// </summary>
|
|||
|
/// <returns>the float location for the line Y</returns>
|
|||
|
private float GetLineVerticalLocation()
|
|||
|
{
|
|||
|
float Y = 0f;
|
|||
|
switch (this.LineLocation)
|
|||
|
{
|
|||
|
case VerticalAlignment.Top:
|
|||
|
{
|
|||
|
Y = this.Padding.Top + this.LinePadding.Top + 1;
|
|||
|
break;
|
|||
|
}
|
|||
|
case VerticalAlignment.Middle:
|
|||
|
{
|
|||
|
Y = (this.Height - this.Padding.Vertical) / 2;
|
|||
|
break;
|
|||
|
}
|
|||
|
case VerticalAlignment.Bottom:
|
|||
|
{
|
|||
|
Y = (this.Height - this.Padding.Bottom - this.LinePadding.Bottom - 1);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return Y;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Determines the point location for the label text
|
|||
|
/// </summary>
|
|||
|
/// <param name="graphics">Current graphics drawing object</param>
|
|||
|
/// <returns>The PointF location of the label text</returns>
|
|||
|
private PointF GetTextPointF(Graphics graphics)
|
|||
|
{
|
|||
|
SizeF textSize = graphics.MeasureString(this.LabelText, this.Font);
|
|||
|
PointF pointF = new PointF();
|
|||
|
|
|||
|
pointF.Y = this.Padding.Top + this.LabelPadding.Top + 1;
|
|||
|
//If both the line and the label are top aligned,
|
|||
|
// bump the text down, including the line's padding
|
|||
|
if (LineLocation == VerticalAlignment.Top)
|
|||
|
{
|
|||
|
pointF.Y += this.LinePadding.Vertical + 1;
|
|||
|
}
|
|||
|
|
|||
|
switch (this.LabelHorizontalAlignment)
|
|||
|
{
|
|||
|
case HorizontalAlignment.Left:
|
|||
|
{
|
|||
|
pointF.X = this.Padding.Left + this.LabelPadding.Left;
|
|||
|
break;
|
|||
|
}
|
|||
|
case HorizontalAlignment.Center:
|
|||
|
{
|
|||
|
pointF.X = (this.Width - this.Padding.Horizontal) / 2 - (int)textSize.Width / 2;
|
|||
|
break;
|
|||
|
}
|
|||
|
case HorizontalAlignment.Right:
|
|||
|
{
|
|||
|
pointF.X = (this.Width - this.Padding.Right - this.LabelPadding.Right) - (int)textSize.Width;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return pointF;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|