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
{
///
/// 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.
///
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
///
/// An Handler to be registerred on parent control Paint event:
/// ParentControl.Paint += AMTTabControl_instance.OnParentPaintHandler;
///
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
}
}