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(); } } }