using System;
//using System.Windows.Forms;
using Gwen.ControlInternal;
namespace Gwen.Control
{
///
/// Splitter control.
///
public class CrossSplitter : Base
{
private readonly SplitterBar m_VSplitter;
private readonly SplitterBar m_HSplitter;
private readonly SplitterBar m_CSplitter;
private readonly Base[] m_Sections;
private float m_HVal; // 0-1
private float m_VVal; // 0-1
private int m_BarSize; // pixels
private int m_ZoomedSection; // 0-3
///
/// Invoked when one of the panels has been zoomed (maximized).
///
public event GwenEventHandler PanelZoomed;
///
/// Invoked when one of the panels has been unzoomed (restored).
///
public event GwenEventHandler PanelUnZoomed;
///
/// Invoked when the zoomed panel has been changed.
///
public event GwenEventHandler ZoomChanged;
///
/// Initializes a new instance of the class.
///
/// Parent control.
public CrossSplitter(Base parent)
: base(parent)
{
m_Sections = new Base[4];
m_VSplitter = new SplitterBar(this);
m_VSplitter.SetPosition(0, 128);
m_VSplitter.Dragged += OnVerticalMoved;
//m_VSplitter.Cursor = Cursors.SizeNS;
m_HSplitter = new SplitterBar(this);
m_HSplitter.SetPosition(128, 0);
m_HSplitter.Dragged += OnHorizontalMoved;
//m_HSplitter.Cursor = Cursors.SizeWE;
m_CSplitter = new SplitterBar(this);
m_CSplitter.SetPosition(128, 128);
m_CSplitter.Dragged += OnCenterMoved;
//m_CSplitter.Cursor = Cursors.SizeAll;
m_HVal = 0.5f;
m_VVal = 0.5f;
SetPanel(0, null);
SetPanel(1, null);
SetPanel(2, null);
SetPanel(3, null);
SplitterSize = 5;
SplittersVisible = false;
m_ZoomedSection = -1;
}
///
/// Centers the panels so that they take even amount of space.
///
public void CenterPanels()
{
m_HVal = 0.5f;
m_VVal = 0.5f;
Invalidate();
}
///
/// Indicates whether any of the panels is zoomed.
///
public bool IsZoomed { get { return m_ZoomedSection != -1; } }
///
/// Gets or sets a value indicating whether splitters should be visible.
///
public bool SplittersVisible
{
get { return m_CSplitter.ShouldDrawBackground; }
set
{
m_CSplitter.ShouldDrawBackground = value;
m_VSplitter.ShouldDrawBackground = value;
m_HSplitter.ShouldDrawBackground = value;
}
}
///
/// Gets or sets the size of the splitter.
///
public int SplitterSize { get { return m_BarSize; } set { m_BarSize = value; } }
private void UpdateVSplitter()
{
m_VSplitter.MoveTo(m_VSplitter.X, (Height - m_VSplitter.Height) * (m_VVal));
}
private void UpdateHSplitter()
{
m_HSplitter.MoveTo( ( Width - m_HSplitter.Width ) * ( m_HVal ), m_HSplitter.Y );
}
private void UpdateCSplitter()
{
m_CSplitter.MoveTo((Width - m_CSplitter.Width) * (m_HVal), (Height - m_CSplitter.Height) * (m_VVal));
}
protected void OnCenterMoved(Base control)
{
CalculateValueCenter();
Invalidate();
}
protected void OnVerticalMoved(Base control)
{
m_VVal = CalculateValueVertical();
Invalidate();
}
protected void OnHorizontalMoved(Base control)
{
m_HVal = CalculateValueHorizontal();
Invalidate();
}
private void CalculateValueCenter()
{
m_HVal = m_CSplitter.X / (float)(Width - m_CSplitter.Width);
m_VVal = m_CSplitter.Y / (float)(Height - m_CSplitter.Height);
}
private float CalculateValueVertical()
{
return m_VSplitter.Y / (float)(Height - m_VSplitter.Height);
}
private float CalculateValueHorizontal()
{
return m_HSplitter.X / (float)(Width - m_HSplitter.Width);
}
///
/// Lays out the control's interior according to alignment, padding, dock etc.
///
/// Skin to use.
protected override void Layout(Skin.Base skin)
{
m_VSplitter.SetSize(Width, m_BarSize);
m_HSplitter.SetSize(m_BarSize, Height);
m_CSplitter.SetSize(m_BarSize, m_BarSize);
UpdateVSplitter();
UpdateHSplitter();
UpdateCSplitter();
if (m_ZoomedSection == -1)
{
if (m_Sections[0] != null)
m_Sections[0].SetBounds(0, 0, m_HSplitter.X, m_VSplitter.Y);
if (m_Sections[1] != null)
m_Sections[1].SetBounds(m_HSplitter.X + m_BarSize, 0, Width - (m_HSplitter.X + m_BarSize), m_VSplitter.Y);
if (m_Sections[2] != null)
m_Sections[2].SetBounds(0, m_VSplitter.Y + m_BarSize, m_HSplitter.X, Height - (m_VSplitter.Y + m_BarSize));
if (m_Sections[3] != null)
m_Sections[3].SetBounds(m_HSplitter.X + m_BarSize, m_VSplitter.Y + m_BarSize, Width - (m_HSplitter.X + m_BarSize), Height - (m_VSplitter.Y + m_BarSize));
}
else
{
//This should probably use Fill docking instead
m_Sections[m_ZoomedSection].SetBounds(0, 0, Width, Height);
}
}
///
/// Assigns a control to the specific inner section.
///
/// Section index (0-3).
/// Control to assign.
public void SetPanel(int index, Base panel)
{
m_Sections[index] = panel;
if (panel != null)
{
panel.Dock = Pos.None;
panel.Parent = this;
}
Invalidate();
}
///
/// Gets the specific inner section.
///
/// Section index (0-3).
/// Specified section.
public Base GetPanel(int index)
{
return m_Sections[index];
}
///
/// Internal handler for the zoom changed event.
///
protected void OnZoomChanged()
{
if (ZoomChanged != null)
ZoomChanged.Invoke(this);
if (m_ZoomedSection == -1)
{
if (PanelUnZoomed != null)
PanelUnZoomed.Invoke(this);
}
else
{
if (PanelZoomed != null)
PanelZoomed.Invoke(this);
}
}
///
/// Maximizes the specified panel so it fills the entire control.
///
/// Panel index (0-3).
public void Zoom(int section)
{
UnZoom();
if (m_Sections[section] != null)
{
for (int i = 0; i < 4; i++)
{
if (i != section && m_Sections[i] != null)
m_Sections[i].IsHidden = true;
}
m_ZoomedSection = section;
Invalidate();
}
OnZoomChanged();
}
///
/// Restores the control so all panels are visible.
///
public void UnZoom()
{
m_ZoomedSection = -1;
for (int i = 0; i < 4; i++)
{
if (m_Sections[i] != null)
m_Sections[i].IsHidden = false;
}
Invalidate();
OnZoomChanged();
}
}
}