587 lines
21 KiB
C#
587 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Data;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AMT_SW_GUI
|
|
{
|
|
/// <summary>
|
|
/// Each Form which like to include this TabControl need to register the OnParentPaintHandler of this class
|
|
/// to its Paint event as follows:
|
|
/// ParentControl.Paint += AMTTabControl_instance.OnParentPaintHandler;
|
|
/// Purpose:
|
|
/// This class is renderring itself instead of the system.
|
|
/// Thus, when another window is hover this class control it should get an explicit redraw call from its container.
|
|
/// </summary>
|
|
public partial class AMTTabControl : TabControl
|
|
{
|
|
#region Private Memebers
|
|
|
|
private PaintEventHandler m_OnParentPaintHandler;
|
|
private Color m_SelectedTabBackgroundColor = Color.FromArgb(250, 249, 249);
|
|
private Color m_UnSelectedTabBackgroundColor = Color.FromArgb(151, 182, 205);
|
|
private Brush foregroundBrush;
|
|
private Color foregroundColor = Color.Black;
|
|
private Panel m_TopInternalBackground;
|
|
private Panel m_RightInternalBackground;
|
|
private Panel m_TopLeftInternalBackground;
|
|
private Panel m_TopRightInternalBackground;
|
|
private Panel m_LeftInternalBackground;
|
|
private Image m_identifierImage;
|
|
private int m_identifierWidth;
|
|
private bool RTL;
|
|
#endregion Private Memebers
|
|
|
|
#region Public Methods
|
|
|
|
private bool hasfocus;
|
|
public AMTTabControl()
|
|
{
|
|
InitializeComponent();
|
|
Init();
|
|
TabSchema = this.schema;
|
|
hasfocus = true;
|
|
LostFocus += new EventHandler(AMTTabControl_LostFocus);
|
|
RightToLeftChanged += new EventHandler(AMTTabControl_RightToLeftChanged);
|
|
}
|
|
|
|
public enum Schema
|
|
{
|
|
FamilyWhiteBg,
|
|
Family,
|
|
SCS,
|
|
NONE
|
|
}
|
|
#endregion Public Methods
|
|
|
|
#region Private Methods
|
|
private void Init()
|
|
{
|
|
this.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;
|
|
m_OnParentPaintHandler = new PaintEventHandler(OnParentPaint);
|
|
Point temp = Padding;
|
|
temp.X = temp.X + 3;
|
|
Padding = temp;
|
|
RTL = (RightToLeft == RightToLeft.Yes);
|
|
if (RTL)
|
|
m_identifierWidth = this.Location.X * 2 + this.ClientRectangle.Width - m_identifierWidth -1;
|
|
}
|
|
|
|
private void AMTTabControl_RightToLeftChanged(object sender, EventArgs e)
|
|
{
|
|
RTL = (RightToLeft == RightToLeft.Yes);
|
|
if (RTL)
|
|
m_identifierWidth = this.Location.X * 2 + this.ClientRectangle.Width - m_identifierWidth - 1;
|
|
|
|
}
|
|
|
|
private void OnParentPaint(object sender, PaintEventArgs e)
|
|
{
|
|
// this.Refresh();
|
|
}
|
|
|
|
|
|
bool patched = false;
|
|
private void PatchInternalBackground(DrawItemEventArgs e)
|
|
{
|
|
// add the internal background "patchy" panels
|
|
if (null != m_RightInternalBackground && !patched)
|
|
{
|
|
m_RightInternalBackground.BackColor = panelColor;//area on right of all tabs
|
|
m_RightInternalBackground.BackgroundImage = panelBackImage;
|
|
}
|
|
if (null != m_TopInternalBackground && !patched)
|
|
{
|
|
m_TopInternalBackground.BackColor = panelColor;//area on top of selected tab
|
|
m_TopInternalBackground.BackgroundImage = m_identifierImage;
|
|
}
|
|
if (null != m_TopRightInternalBackground && !patched)
|
|
{
|
|
m_TopRightInternalBackground.BackColor = panelColor; //area on top of above area
|
|
m_TopRightInternalBackground.BackgroundImage = panelBackImage;
|
|
}
|
|
if (null != m_TopLeftInternalBackground && !patched)
|
|
{
|
|
m_TopLeftInternalBackground.BackColor = panelColor;//top area to left of selected tab
|
|
m_TopLeftInternalBackground.BackgroundImage = panelBackImage;
|
|
}
|
|
if (null != m_LeftInternalBackground && !patched)
|
|
{
|
|
m_LeftInternalBackground.BackColor = panelColor;
|
|
m_LeftInternalBackground.BackgroundImage = panelBackImage;
|
|
patched = true;
|
|
}
|
|
|
|
int x, y, w, h, padding;
|
|
padding = 3;
|
|
x = y = w = h = 0;
|
|
|
|
// accumulate container offset in parent
|
|
x = this.Location.X;
|
|
y = this.Location.Y;
|
|
|
|
// Fill the right side of the last tabPage with m_RightInternalBackground Panel
|
|
if (e.Index == (this.TabCount - 1))
|
|
{
|
|
if (this.SelectedIndex == e.Index)
|
|
{
|
|
x += (RTL) ? 0 : e.Bounds.X + e.Bounds.Width;
|
|
y += this.ClientRectangle.Y + padding;
|
|
w = this.ClientRectangle.Width - (e.Bounds.X + e.Bounds.Width);
|
|
h = e.Bounds.Height - 2 * padding;
|
|
m_RightInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
else
|
|
{
|
|
x += (RTL) ? 0 : e.Bounds.X + e.Bounds.Width + padding;
|
|
y += this.ClientRectangle.Y + padding;
|
|
w = this.ClientRectangle.Width - (e.Bounds.X + e.Bounds.Width) - padding;
|
|
h = e.Bounds.Height;
|
|
m_RightInternalBackground.BringToFront();
|
|
m_RightInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
}
|
|
|
|
// Reset x, y
|
|
x = this.Location.X;
|
|
y = this.Location.Y;
|
|
|
|
// Fill the top right side with m_TopRightInternalBackground Panel
|
|
if (this.SelectedIndex == e.Index)
|
|
{
|
|
if (m_identifierWidth > 0 && m_identifierImage != null && SelectedIndex == 0)
|
|
{
|
|
x = (RTL) ? 0 : Math.Max(m_identifierWidth, x + e.Bounds.Width - 1);
|
|
w = (RTL) ? m_identifierWidth : this.ClientRectangle.Width - x + 2 + this.Location.X;
|
|
}
|
|
else
|
|
{
|
|
x += (RTL) ? 0 : (e.Bounds.X + e.Bounds.Width - 2);
|
|
w = this.ClientRectangle.Width - (e.Bounds.X + e.Bounds.Width) + 2;
|
|
|
|
}
|
|
y += this.ClientRectangle.Y;
|
|
h = padding;
|
|
m_TopRightInternalBackground.BringToFront();
|
|
m_TopRightInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
|
|
// Reset x, y
|
|
x = this.Location.X;
|
|
y = this.Location.Y;
|
|
|
|
// Fill the top of the selected tab with m_TopInternalBackground Panel
|
|
if (m_identifierWidth > 0 && m_identifierImage != null)
|
|
{
|
|
// Reset x, y
|
|
x = this.Location.X;
|
|
y = this.Location.Y;
|
|
if (this.SelectedIndex > 0)
|
|
{
|
|
|
|
if (this.SelectedIndex == e.Index)
|
|
{
|
|
m_TopInternalBackground.BringToFront();
|
|
x = (RTL) ? Math.Max(this.Width + this.Location.X - e.Bounds.X, m_identifierWidth) : x - 2;
|
|
|
|
y += this.ClientRectangle.Y -1;
|
|
w = (RTL) ? this.Location.X + this.Width - x : Math.Min(e.Bounds.X + padding, m_identifierWidth - x + 2);
|
|
h = padding + 1;
|
|
m_TopInternalBackground.SetBounds(x, y, w, h);
|
|
m_TopInternalBackground.Margin = new Padding(0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this.SelectedIndex == e.Index)
|
|
{
|
|
// m_TopInternalBackground.SendToBack();
|
|
m_TopInternalBackground.BringToFront();
|
|
x = (RTL) ? m_identifierWidth : x + (e.Bounds.X + e.Bounds.Width - 2);
|
|
y += this.ClientRectangle.Y -1;
|
|
w = (RTL) ? this.Location.X + this.Width - x - e.Bounds.Width : m_identifierWidth - x + 2;
|
|
h = padding + 1;
|
|
m_TopInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Reset x, y
|
|
x = this.Location.X;
|
|
y = this.Location.Y;
|
|
|
|
// Fill the top left side with m_TopLeftInternalBackground Panel
|
|
if (this.SelectedIndex == e.Index)
|
|
{
|
|
if (m_identifierWidth > 0 && m_identifierImage != null)
|
|
{
|
|
int temp = x;
|
|
x += (RTL) ? this.Width - e.Bounds.X : Math.Min(e.Bounds.X + padding, m_identifierWidth - temp + 2);
|
|
w = (RTL) ? m_identifierWidth - x : e.Bounds.X + padding - Math.Min(e.Bounds.X + padding, m_identifierWidth - temp + 2);
|
|
|
|
}
|
|
else
|
|
{
|
|
w = e.Bounds.X + padding - 3;
|
|
if (RTL)
|
|
x = this.Width + x - e.Bounds.X;
|
|
}
|
|
|
|
y += this.ClientRectangle.Y;
|
|
h = padding;
|
|
m_TopLeftInternalBackground.BringToFront();
|
|
m_TopLeftInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
|
|
// Reset x, y
|
|
x = (RTL) ? this.ClientRectangle.Width + this.Location.X - 3 : this.Location.X;
|
|
y = this.Location.Y;
|
|
|
|
// Fill the left side with m_LeftInternalBackground Panel
|
|
if (this.SelectedIndex == 0)
|
|
{
|
|
y += this.ClientRectangle.Y + padding;
|
|
w = padding;
|
|
h = e.Bounds.Height - padding;
|
|
m_LeftInternalBackground.BackColor = m_SelectedTabBackgroundColor;
|
|
// if (m_LeftInternalBackground.BackgroundImage != null)
|
|
{
|
|
m_LeftInternalBackground.BringToFront();
|
|
m_LeftInternalBackground.BackgroundImage = null;
|
|
m_LeftInternalBackground.SetBounds(x, y, w, h);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (e.Index != 0)
|
|
{
|
|
x += e.Bounds.X;
|
|
}
|
|
w = padding;
|
|
y += this.ClientRectangle.Y;
|
|
h = e.Bounds.Height + 4;
|
|
|
|
if (m_LeftInternalBackground.BackgroundImage == null/* && m_identifierImage != null*/)
|
|
{
|
|
m_LeftInternalBackground.BringToFront();
|
|
m_LeftInternalBackground.BackgroundImage = (m_identifierImage != null) ? m_identifierImage : panelBackImage;//Properties.Resources.transparent_highlight;
|
|
m_LeftInternalBackground.BackColor = Color.Transparent;
|
|
m_LeftInternalBackground.SetBounds(x, y, w, h);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
#endregion Private Methods
|
|
|
|
#region Protected Methods
|
|
|
|
protected override void OnDrawItem(DrawItemEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
SuspendLayout();
|
|
Font font;
|
|
Brush backgroundBrush;
|
|
|
|
Brush backgroundBrushSelected;
|
|
TabPageCollection tabPages = this.TabPages;
|
|
|
|
if (e.Index == this.SelectedIndex)
|
|
{
|
|
font = new Font(e.Font, FontStyle.Regular);
|
|
backgroundBrush = new SolidBrush(m_SelectedTabBackgroundColor);
|
|
|
|
}
|
|
else
|
|
{
|
|
font = e.Font;
|
|
backgroundBrush = new SolidBrush(m_UnSelectedTabBackgroundColor);
|
|
|
|
}
|
|
backgroundBrushSelected = new SolidBrush(m_SelectedTabBackgroundColor);
|
|
|
|
/// set the alignment of the caption
|
|
string tabName = tabPages[e.Index].Text;
|
|
StringFormat sf = new StringFormat();
|
|
sf.Alignment = StringAlignment.Center;
|
|
|
|
/// Draw border frame
|
|
|
|
SelectedTab.BorderStyle = (schema == Schema.SCS) ? System.Windows.Forms.BorderStyle.FixedSingle : System.Windows.Forms.BorderStyle.None;
|
|
|
|
Rectangle borderRect;
|
|
int borderWidth = 4;
|
|
/// left border
|
|
Rectangle containerRect = this.ClientRectangle;
|
|
borderRect = new Rectangle(containerRect.X, containerRect.Y + ItemSize.Height, borderWidth, containerRect.Height + 5);
|
|
if (e.Index == 0 && e.Index == this.SelectedIndex)
|
|
{
|
|
borderRect.Y -= ItemSize.Height;
|
|
borderRect.Height += ItemSize.Height;
|
|
}
|
|
e.Graphics.FillRectangle(backgroundBrush, borderRect);
|
|
/// bottom border
|
|
borderRect.X = containerRect.X;
|
|
borderRect.Y = (containerRect.Y + containerRect.Height) - borderWidth;
|
|
borderRect.Width = containerRect.Width;
|
|
borderRect.Height = borderWidth;
|
|
e.Graphics.FillRectangle(backgroundBrush, borderRect);
|
|
/// right border
|
|
borderRect.X = (containerRect.X + containerRect.Width) - borderWidth;
|
|
borderRect.Y = containerRect.Y + ItemSize.Height;
|
|
borderRect.Width = borderWidth;
|
|
borderRect.Height = containerRect.Height;
|
|
e.Graphics.FillRectangle(backgroundBrush, borderRect);
|
|
/// top border
|
|
borderRect.X = containerRect.X;
|
|
borderRect.Y = containerRect.Y + ItemSize.Height;
|
|
borderRect.Width = containerRect.Width;
|
|
borderRect.Height = borderWidth;
|
|
e.Graphics.FillRectangle(backgroundBrushSelected, borderRect);
|
|
|
|
// drawing the tab itself
|
|
Rectangle tabRect = (RTL) ? new Rectangle(containerRect.Width - e.Bounds.X - e.Bounds.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height - 2) :
|
|
new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height - 2);
|
|
|
|
if (e.Index != this.SelectedIndex)
|
|
{
|
|
// set appropriate height for the unselected tabs
|
|
tabRect.Height = tabRect.Height + 3;
|
|
}
|
|
//else
|
|
// if (e.Index == 0)
|
|
// {
|
|
// tabRect.X += (RTL) ? 5 : -5;
|
|
// tabRect.Width += (RTL) ? -5 : 5;
|
|
// }
|
|
e.Graphics.FillRectangle(backgroundBrush, tabRect);
|
|
|
|
/* Prepare to string drawing */
|
|
Rectangle r = tabRect;
|
|
int x = (RTL) ? this.Width - r.X - r.Width : r.X;
|
|
|
|
r = new Rectangle(x, r.Y, r.Width, e.Bounds.Height);
|
|
|
|
// e.Graphics.DrawString(tabName, font, foregroundBrush, r, sf);
|
|
TextRenderer.DrawText(e.Graphics, tabName, font, r, foregroundColor);
|
|
|
|
sf.Dispose();
|
|
if (e.Index == this.SelectedIndex)
|
|
{
|
|
font.Dispose();
|
|
}
|
|
else
|
|
{
|
|
backgroundBrush.Dispose();
|
|
}
|
|
backgroundBrushSelected.Dispose();
|
|
|
|
PatchInternalBackground(e);
|
|
ResumeLayout();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// should log to debug log something here
|
|
}
|
|
}
|
|
|
|
|
|
protected override void OnGotFocus(EventArgs e)
|
|
{
|
|
if (!hasfocus)
|
|
{
|
|
this.Refresh();
|
|
}
|
|
hasfocus = true;
|
|
base.OnGotFocus(e);
|
|
}
|
|
|
|
public void gotFocus()
|
|
{
|
|
OnGotFocus(null);
|
|
}
|
|
|
|
void AMTTabControl_LostFocus(object sender, EventArgs e)
|
|
{
|
|
hasfocus = false;
|
|
this.Refresh();
|
|
|
|
}
|
|
|
|
|
|
protected override void OnMouseLeave(EventArgs e)
|
|
{
|
|
// base.OnMouseLeave(e);
|
|
// this.Refresh();
|
|
}
|
|
|
|
protected override void OnMouseHover(EventArgs e)
|
|
{
|
|
// base.OnMouseHover(e);
|
|
// this.Refresh();
|
|
}
|
|
|
|
protected override void OnMouseEnter(EventArgs e)
|
|
{
|
|
//base.OnMouseEnter(e);
|
|
}
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
{
|
|
//base.OnMouseMove(e);
|
|
}
|
|
protected override void OnEnter(EventArgs e)
|
|
{
|
|
//base.OnEnter(e);
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
/// An Handler to be registerred on parent control Paint event:
|
|
/// ParentControl.Paint += AMTTabControl_instance.OnParentPaintHandler;
|
|
/// </summary>
|
|
public PaintEventHandler OnParentPaintHandler
|
|
{
|
|
get { return m_OnParentPaintHandler; }
|
|
}
|
|
|
|
public Color SelectedTabBackgroundColor
|
|
{
|
|
get { return m_SelectedTabBackgroundColor; }
|
|
set { if (TabSchema == Schema.NONE) m_SelectedTabBackgroundColor = value; }
|
|
}
|
|
|
|
public Color TabTextColor
|
|
{
|
|
get { return foregroundColor; }
|
|
set
|
|
{
|
|
if (TabSchema == Schema.NONE)
|
|
{
|
|
foregroundColor = value; ;
|
|
foregroundBrush = new SolidBrush(foregroundColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Image IdentifierImage
|
|
{
|
|
get { return m_identifierImage; }
|
|
set
|
|
{
|
|
if (TabSchema == Schema.NONE || TabSchema == Schema.Family || TabSchema == Schema.FamilyWhiteBg)
|
|
{
|
|
m_identifierImage = value;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public int IdentifierWidth
|
|
{
|
|
get { return m_identifierWidth; }
|
|
set { m_identifierWidth = value; }
|
|
}
|
|
|
|
|
|
|
|
public Color UnSelectedTabBackgroundColor
|
|
{
|
|
get { return m_UnSelectedTabBackgroundColor; }
|
|
set { if (TabSchema == Schema.NONE) m_UnSelectedTabBackgroundColor = value; }
|
|
}
|
|
|
|
public Panel RightInternalBackground
|
|
{
|
|
get { return m_RightInternalBackground; }
|
|
set { m_RightInternalBackground = value; }
|
|
}
|
|
|
|
public Panel TopInternalBackground
|
|
{
|
|
get { return m_TopInternalBackground; }
|
|
set { m_TopInternalBackground = value; }
|
|
}
|
|
public Panel TopLeftInternalBackground
|
|
{
|
|
get { return m_TopLeftInternalBackground; }
|
|
set { m_TopLeftInternalBackground = value; }
|
|
}
|
|
|
|
public Panel TopRightInternalBackground
|
|
{
|
|
get { return m_TopRightInternalBackground; }
|
|
set { m_TopRightInternalBackground = value; }
|
|
}
|
|
|
|
public Panel LeftInternalBackground
|
|
{
|
|
get { return m_LeftInternalBackground; }
|
|
set { m_LeftInternalBackground = value; }
|
|
}
|
|
|
|
|
|
private Color panelColor = Color.Transparent;
|
|
private Image panelBackImage = Properties.Resources.transparent_highlight;
|
|
private Schema schema;
|
|
public Schema TabSchema
|
|
{
|
|
get { return schema; }
|
|
set
|
|
{
|
|
schema = value;
|
|
switch (schema)
|
|
{
|
|
case Schema.Family:
|
|
{
|
|
m_SelectedTabBackgroundColor = Color.FromArgb(250, 249, 249);
|
|
m_UnSelectedTabBackgroundColor = Color.FromArgb(151, 182, 205);
|
|
panelColor = Color.Transparent;
|
|
panelBackImage = Properties.Resources.transparent_highlight;
|
|
foregroundBrush = Brushes.Black;
|
|
return;
|
|
|
|
}
|
|
case Schema.SCS :
|
|
|
|
{
|
|
m_SelectedTabBackgroundColor = Color.FromArgb(86, 126, 185);
|
|
m_UnSelectedTabBackgroundColor = Color.FromArgb(151, 182, 205);
|
|
panelColor = Color.White;
|
|
panelBackImage = Properties.Resources.inner_pane_center;
|
|
foregroundBrush = new SolidBrush(Color.White);
|
|
return;
|
|
}
|
|
case Schema.FamilyWhiteBg:
|
|
{
|
|
m_SelectedTabBackgroundColor = Color.FromArgb(86, 126, 185);
|
|
m_UnSelectedTabBackgroundColor = Color.FromArgb(151, 182, 205);
|
|
panelColor = Color.White;
|
|
panelBackImage = Properties.Resources.inner_pane_center;
|
|
foregroundBrush = new SolidBrush(Color.White);
|
|
return;
|
|
|
|
}
|
|
|
|
case Schema.NONE:
|
|
{
|
|
return;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Properties
|
|
|
|
}
|
|
|
|
} |