BizHawk/BizHawk.Client.EmuHawk/config/AnalogRangeConfig.cs

197 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk
{
public partial class AnalogRangeConfig : Panel
{
private const int ScaleFactor = 4;
private const int _3DPadding = 5;
private readonly Pen _blackPen;
private readonly Pen _bluePen;
private int _maxX = 127;
private int _maxY = 127;
private bool _radial = false;
public int MaxX
{
get
{
return _maxX;
}
set
{
_maxX = value;
Refresh();
Changed();
}
}
public int MaxY
{
get
{
return _maxY;
}
set
{
_maxY = value;
Refresh();
Changed();
}
}
public bool Radial
{
get
{
return _radial;
}
set
{
_radial = value;
Refresh();
Changed();
}
}
private int ScaledX
{
get { return MaxX / ScaleFactor; }
}
private int ScaledY
{
get { return MaxY / ScaleFactor; }
}
private Point TopLeft
{
get
{
var centerX = Size.Width / 2;
var centerY = Size.Height / 2;
return new Point(centerX - ScaledX, centerY - ScaledY);
}
}
public AnalogRangeConfig()
{
MaxX = 127;
MaxY = 127;
Size = new Size(65, 65);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, true);
BackColor = Color.Gray;
BorderStyle = BorderStyle.Fixed3D;
_blackPen = new Pen(Brushes.Black);
_bluePen = new Pen(Brushes.Cyan);
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(SystemBrushes.Control, 0, 0, Width, Height);
e.Graphics.FillEllipse(Brushes.White, 0, 0, Width - _3DPadding, Height - _3DPadding);
e.Graphics.DrawEllipse(_blackPen, 0, 0, Width - _3DPadding, Height - _3DPadding);
if (Radial)
{
e.Graphics.DrawEllipse(
_bluePen,
TopLeft.X,
TopLeft.Y,
ScaledX * 2 - 4,
ScaledY * 2 - 4);
}
else
{
e.Graphics.DrawRectangle(
_bluePen,
TopLeft.X,
TopLeft.Y,
ScaledX * 2 - 3,
ScaledY * 2 - 3);
}
base.OnPaint(e);
}
private bool _isDragging = false;
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_isDragging = true;
DoDrag(e.X, e.Y);
}
else if (e.Button == MouseButtons.Right)
{
Radial ^= true;
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_isDragging = false;
}
base.OnMouseUp(e);
}
private void DoDrag(int x, int y)
{
if (_isDragging)
{
var centerX = Size.Width / 2;
var centerY = Size.Height / 2;
var offsetx = Math.Abs(centerX - x) * ScaleFactor;
var offsety = Math.Abs(centerY - y) * ScaleFactor;
MaxX = Math.Min(offsetx, sbyte.MaxValue);
MaxY = Math.Min(offsety, sbyte.MaxValue);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
DoDrag(e.X, e.Y);
base.OnMouseMove(e);
}
public Action ChangeCallback { get; set; }
private void Changed()
{
if (ChangeCallback != null)
{
ChangeCallback();
}
}
}
}