160 lines
4.1 KiB
C#
160 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace Mesen.GUI.Controls
|
|
{
|
|
class ctrlSplitContainer : SplitContainer
|
|
{
|
|
public event EventHandler PanelCollapsed;
|
|
public event EventHandler PanelExpanded;
|
|
private int _originalDistance = 0;
|
|
private int _originalMinSize = 0;
|
|
private bool _preventExpand = false;
|
|
|
|
public ctrlSplitContainer()
|
|
{
|
|
this.DoubleBuffered = true;
|
|
this.SplitterMoving += ctrlSplitContainer_SplitterMoving;
|
|
}
|
|
|
|
private void ctrlSplitContainer_SplitterMoving(object sender, SplitterCancelEventArgs e)
|
|
{
|
|
if(_originalMinSize > 0) {
|
|
e.Cancel = true;
|
|
this.BeginInvoke((MethodInvoker)(() => {
|
|
this.ExpandPanel();
|
|
}));
|
|
}
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
|
|
if(this.Orientation == Orientation.Horizontal) {
|
|
int top = this.SplitterDistance + 1;
|
|
int center = this.Width / 2;
|
|
e.Graphics.DrawLine(Pens.DarkGray, center - 100, top, center + 100, top);
|
|
top+=2;
|
|
e.Graphics.DrawLine(Pens.DarkGray, center - 100, top, center + 100, top);
|
|
} else {
|
|
int center = this.Height / 2;
|
|
int left = this.SplitterDistance + 1;
|
|
e.Graphics.DrawLine(Pens.DarkGray, left, center - 100, left, center + 100);
|
|
left+=2;
|
|
e.Graphics.DrawLine(Pens.DarkGray, left, center - 100, left, center + 100);
|
|
}
|
|
}
|
|
|
|
protected override void OnDoubleClick(EventArgs e)
|
|
{
|
|
base.OnDoubleClick(e);
|
|
|
|
if(_originalMinSize == 0) {
|
|
this.CollapsePanel();
|
|
_preventExpand = true;
|
|
} else {
|
|
this.ExpandPanel();
|
|
}
|
|
}
|
|
|
|
public void ExpandPanel()
|
|
{
|
|
if(this.FixedPanel == FixedPanel.Panel1) {
|
|
throw new Exception("Not implemented");
|
|
} else if(this.FixedPanel == FixedPanel.Panel2) {
|
|
if(_originalMinSize > 0) {
|
|
this.Panel2MinSize = _originalMinSize;
|
|
this.SplitterDistance = _originalDistance;
|
|
_originalMinSize = 0;
|
|
}
|
|
this.PanelExpanded?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
public void CollapsePanel()
|
|
{
|
|
if(this.FixedPanel == FixedPanel.Panel1) {
|
|
throw new Exception("Not implemented");
|
|
} else if(this.FixedPanel == FixedPanel.Panel2) {
|
|
_originalDistance = this.SplitterDistance;
|
|
_originalMinSize = this.Panel2MinSize;
|
|
this.Panel2MinSize = 4;
|
|
this.SplitterDistance = this.Orientation == Orientation.Horizontal ? this.Height : this.Width;
|
|
|
|
this.PanelCollapsed?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
public int GetSplitterDistance()
|
|
{
|
|
return _originalMinSize > 0 ? _originalDistance : this.SplitterDistance;
|
|
}
|
|
|
|
DateTime _lastResize = DateTime.MinValue;
|
|
protected override void OnResize(EventArgs e)
|
|
{
|
|
base.OnResize(e);
|
|
|
|
//Horrible patch to fix what looks like a resize bug in SplitContainers
|
|
//Resizing the window sometimes doesn't resize the inner panels properly
|
|
//causing their content to go partially offscreen.
|
|
//This code alters SplitterDistance approx 100ms after the last resize event
|
|
//to fix the display bug
|
|
if(this.IsHandleCreated) {
|
|
bool firstResize;
|
|
lock(this) {
|
|
firstResize = _lastResize == DateTime.MinValue;
|
|
_lastResize = DateTime.Now;
|
|
}
|
|
if(firstResize) {
|
|
Task.Run(() => {
|
|
while((DateTime.Now - _lastResize).Milliseconds < 100) {
|
|
System.Threading.Thread.Sleep(100);
|
|
}
|
|
|
|
this.BeginInvoke((MethodInvoker)(() => {
|
|
if(_originalMinSize == 0) {
|
|
this.SuspendLayout();
|
|
this.Panel1.SuspendLayout();
|
|
this.Panel2.SuspendLayout();
|
|
try {
|
|
if(this.Width > 0 && this.Height > 0) {
|
|
this.SplitterDistance++;
|
|
this.SplitterDistance--;
|
|
}
|
|
} catch {
|
|
} finally {
|
|
this.ResumeLayout();
|
|
this.Panel1.ResumeLayout();
|
|
this.Panel2.ResumeLayout();
|
|
}
|
|
}
|
|
this.Invalidate();
|
|
lock(this) {
|
|
_lastResize = DateTime.MinValue;
|
|
}
|
|
}));
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnMouseUp(MouseEventArgs e)
|
|
{
|
|
base.OnMouseUp(e);
|
|
this.Panel1.Focus();
|
|
|
|
if(!_preventExpand && _originalMinSize > 0) {
|
|
this.ExpandPanel();
|
|
}
|
|
|
|
_preventExpand = false;
|
|
}
|
|
}
|
|
}
|