BizHawk/BizHawk.Client.EmuHawk/tools/TAStudio/InputRoll.cs

412 lines
9.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
2014-08-07 18:32:09 +00:00
using BizHawk.Client.EmuHawk.CustomControls;
namespace BizHawk.Client.EmuHawk
{
public class InputRoll : Control
{
2014-08-09 13:13:24 +00:00
private readonly GDIRenderer Gdi;
2014-08-08 18:30:57 +00:00
private readonly RollColumns Columns = new RollColumns();
2014-08-09 13:13:24 +00:00
private bool NeedToReDrawColumn = false;
private int _horizontalOrientedColumnWidth = 0;
2014-08-09 16:11:25 +00:00
private Size _charSize;
2014-08-09 13:13:24 +00:00
public InputRoll()
{
2014-08-07 18:32:09 +00:00
CellPadding = 3;
//SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
2014-08-08 13:36:37 +00:00
SetStyle(ControlStyles.Opaque, true);
2014-08-09 16:11:25 +00:00
this.Font = new Font("Courier New", 8); // Only support fixed width
2014-08-08 13:36:37 +00:00
//BackColor = Color.Transparent;
2014-08-08 13:42:05 +00:00
2014-08-09 13:13:24 +00:00
Gdi = new GDIRenderer(this);
2014-08-09 16:11:25 +00:00
_charSize = Gdi.MeasureString("A", this.Font);
}
protected override void Dispose(bool disposing)
{
Gdi.Dispose();
base.Dispose(disposing);
}
#region Properties
2014-08-07 18:32:09 +00:00
/// <summary>
/// Gets or sets the amount of padding on the text inside a cell
/// </summary>
[DefaultValue(3)]
public int CellPadding { get; set; }
// TODO: remove this, it is put here for more convenient replacing of a virtuallistview in tools with the need to refactor code
public bool VirtualMode { get; set; }
/// <summary>
/// Gets or sets whether the control is horizontal or vertical
/// </summary>
[Category("Behavior")]
public bool HorizontalOrientation { get; set; }
/// <summary>
/// Gets or sets the sets the virtual number of items to be displayed.
/// </summary>
[Category("Behavior")]
public int ItemCount { get; set; }
/// <summary>
/// Gets or sets the sets the columns can be resized
/// </summary>
[Category("Behavior")]
public bool AllowColumnResize { get; set; }
/// <summary>
/// Gets or sets the sets the columns can be reordered
/// </summary>
[Category("Behavior")]
public bool AllowColumnReorder { get; set; }
#endregion
#region Event Handlers
/// <summary>
/// Retrieve the background color for a Listview cell (item and subitem).
/// </summary>
/// <param name="index">Listview item (row).</param>
/// <param name="column">Listview subitem (column).</param>
/// <param name="color">Background color to use</param>
public delegate void QueryItemBkColorHandler(int index, int column, ref Color color);
/// <summary>
/// Retrieve the text for a Listview cell (item and subitem).
/// </summary>
/// <param name="index">Listview item (row).</param>
/// <param name="column">Listview subitem (column).</param>
/// <param name="text">Text to display.</param>
public delegate void QueryItemTextHandler(int index, int column, out string text);
/// <summary>
/// Fire the QueryItemBkColor event which requests the background color for the passed Listview cell
/// </summary>
[Category("Virtual")] // TODO: can I make these up?
public event QueryItemBkColorHandler QueryItemBkColor;
/// <summary>
/// Fire the QueryItemText event which requests the text for the passed Listview cell.
/// </summary>
[Category("Virtual")]
public event QueryItemTextHandler QueryItemText;
#endregion
#region Public Methods
public string UserSettingsSerialized()
{
return string.Empty; // TODO
}
2014-08-08 18:30:57 +00:00
public void AddColumns(IEnumerable<RollColumn> columns)
{
Columns.AddRange(columns);
ColumnChanged();
}
public void AddColumn(RollColumn column)
{
Columns.Add(column);
ColumnChanged();
}
#endregion
#region Paint
2014-08-09 13:13:24 +00:00
private void DrawColumnBg(GDIRenderer gdi, PaintEventArgs e)
2014-08-07 18:32:09 +00:00
{
2014-08-09 13:13:24 +00:00
gdi.SetBrush(SystemColors.ControlLight);
2014-08-09 16:11:25 +00:00
gdi.SetSolidPen(Color.Black);
2014-08-09 13:13:24 +00:00
2014-08-07 18:32:09 +00:00
if (HorizontalOrientation)
{
2014-08-09 13:13:24 +00:00
var colWidth = _horizontalOrientedColumnWidth;
2014-08-09 16:11:25 +00:00
gdi.DrawRectangle(0, 0, colWidth, Height);
gdi.FillRectangle(1, 1, colWidth - 3, Height - 3);
2014-08-08 02:09:59 +00:00
int start = 0;
foreach (var column in Columns)
{
start += CellHeight;
2014-08-09 16:11:25 +00:00
gdi.Line(1, start, colWidth - 1, start);
2014-08-08 02:09:59 +00:00
}
2014-08-07 18:32:09 +00:00
}
else
{
2014-08-09 16:11:25 +00:00
gdi.DrawRectangle(0, 0, Width, CellHeight);
gdi.FillRectangle(1, 1, Width - 3, CellHeight - 3);
2014-08-07 18:32:09 +00:00
2014-08-08 02:09:59 +00:00
int start = 0;
foreach (var column in Columns)
{
2014-08-09 16:11:25 +00:00
start += CalcWidth(column);
2014-08-09 13:13:24 +00:00
gdi.Line(start, 0, start, CellHeight);
2014-08-08 02:09:59 +00:00
}
2014-08-07 18:32:09 +00:00
}
}
2014-08-09 16:11:25 +00:00
private void DrawBg(GDIRenderer gdi, PaintEventArgs e)
2014-08-07 18:32:09 +00:00
{
2014-08-09 16:11:25 +00:00
var startPoint = StartBg();
2014-08-07 18:32:09 +00:00
2014-08-09 16:11:25 +00:00
gdi.SetBrush(Color.White);
gdi.SetSolidPen(Color.Black);
gdi.FillRectangle(startPoint.X, startPoint.Y, Width, Height);
gdi.DrawRectangle(startPoint.X, startPoint.Y, Width, Height);
2014-08-07 18:32:09 +00:00
2014-08-09 16:11:25 +00:00
gdi.SetSolidPen(SystemColors.ControlLight);
2014-08-07 18:32:09 +00:00
if (HorizontalOrientation)
{
2014-08-09 16:11:25 +00:00
// Columns
for (int i = 1; i < Width / CellWidth; i++)
{
var x = _horizontalOrientedColumnWidth + (i * CellWidth);
gdi.Line(x, 1, x, Columns.Count * CellHeight);
}
2014-08-07 18:32:09 +00:00
2014-08-09 16:11:25 +00:00
// Rows
for (int i = 1; i < Columns.Count + 1; i++)
{
gdi.Line(_horizontalOrientedColumnWidth, i * CellHeight, Width - 2, i * CellHeight);
}
2014-08-07 18:32:09 +00:00
}
else
{
2014-08-09 16:11:25 +00:00
// Columns
int x = 0;
int y = CellHeight;
foreach (var column in Columns)
{
x += CalcWidth(column);
gdi.Line(x, y, x, Height - 1);
}
2014-08-07 18:32:09 +00:00
2014-08-09 16:11:25 +00:00
// Rows
for (int i = 2; i < Height / CellHeight; i++)
{
gdi.Line(1, (i * CellHeight) + 1, Width - 2, (i * CellHeight) + 1);
}
2014-08-07 18:32:09 +00:00
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
2014-08-08 13:42:05 +00:00
// Do nothing, and this should never be called
}
2014-08-09 13:13:24 +00:00
private void DrawColumnText(GDIRenderer gdi, PaintEventArgs e)
2014-08-08 02:09:59 +00:00
{
if (HorizontalOrientation)
{
int start = 0;
foreach (var column in Columns)
{
var point = new Point(CellPadding, start + CellPadding);
gdi.PrepDrawString(column.Text, this.Font, this.ForeColor, point);
gdi.DrawString(column.Text, this.Font, point);
2014-08-08 02:09:59 +00:00
start += CellHeight;
}
}
else
{
2014-08-09 13:13:24 +00:00
int start = CellPadding;
2014-08-08 02:09:59 +00:00
foreach(var column in Columns)
{
2014-08-09 13:13:24 +00:00
var point = new Point(start + CellPadding, CellPadding);
gdi.PrepDrawString(column.Text, this.Font, this.ForeColor, point);
gdi.DrawString(column.Text, this.Font, point);
2014-08-09 16:11:25 +00:00
start += CalcWidth(column);
2014-08-08 02:09:59 +00:00
}
}
}
private void DrawData(GDIRenderer gdi, PaintEventArgs e)
{
if (QueryItemText != null)
{
if (HorizontalOrientation)
{
}
else
{
var visibleRows = (Height / CellHeight) - 1;
for (int i = 1; i < visibleRows; i++)
{
int x = 1;
for (int j = 0; j < Columns.Count; j++)
{
string text;
var point = new Point(x + CellPadding, i * CellHeight);
QueryItemText(i, j, out text);
gdi.PrepDrawString(text, this.Font, this.ForeColor, point);
gdi.DrawString(text, this.Font, point);
x += CalcWidth(Columns[j]);
}
}
}
}
}
2014-08-08 13:42:05 +00:00
protected override void OnPaint(PaintEventArgs e)
{
Gdi.NewHdc(e.Graphics.GetHdc());
2014-08-08 13:42:05 +00:00
// Header
if (Columns.Any())
2014-08-08 02:09:59 +00:00
{
2014-08-09 13:13:24 +00:00
DrawColumnBg(Gdi, e);
DrawColumnText(Gdi, e);
2014-08-08 02:09:59 +00:00
}
2014-08-08 13:42:05 +00:00
// Background
2014-08-09 13:13:24 +00:00
DrawBg(Gdi, e);
2014-08-08 13:42:05 +00:00
// ForeGround
DrawData(Gdi, e);
}
#endregion
#region Mouse and Key Events
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.R) // Ctrl + R
{
HorizontalOrientation ^= true;
}
base.OnKeyDown(e);
}
#endregion
#region Helpers
private bool NeedToUpdateScrollbar()
{
return true;
}
2014-08-09 13:13:24 +00:00
private Point StartBg()
2014-08-07 18:32:09 +00:00
{
2014-08-09 13:13:24 +00:00
if (Columns.Any())
2014-08-07 18:32:09 +00:00
{
2014-08-09 13:13:24 +00:00
if (HorizontalOrientation)
2014-08-07 18:32:09 +00:00
{
2014-08-09 16:11:25 +00:00
var x = _horizontalOrientedColumnWidth - 1;
2014-08-09 13:13:24 +00:00
var y = 0;
return new Point(x, y);
}
else
{
var x = 0;
2014-08-09 16:11:25 +00:00
var y = CellHeight - 1;
2014-08-09 13:13:24 +00:00
return new Point(x, y);
2014-08-07 18:32:09 +00:00
}
}
2014-08-09 13:13:24 +00:00
return new Point(0, 0);
2014-08-07 23:10:41 +00:00
}
2014-08-08 02:09:59 +00:00
private int CellHeight
{
get
{
2014-08-09 16:11:25 +00:00
return _charSize.Height + (CellPadding * 2);
}
}
2014-08-09 16:11:25 +00:00
private int CellWidth
{
get
{
2014-08-09 16:11:25 +00:00
return _charSize.Width + (CellPadding * 4); // Double the padding for horizontal because it looks better
}
}
private bool NeedsScrollbar
{
get
{
if (HorizontalOrientation)
{
2014-08-09 16:11:25 +00:00
return Width / CellWidth > ItemCount;
}
2014-08-08 02:09:59 +00:00
return Height / CellHeight > ItemCount;
}
}
2014-08-08 18:30:57 +00:00
private void ColumnChanged()
{
NeedToReDrawColumn = true;
2014-08-09 16:11:25 +00:00
var text = Columns.Max(c => c.Text.Length);
_horizontalOrientedColumnWidth = (text * _charSize.Width) + (CellPadding * 2);
}
private int CalcWidth(RollColumn col)
{
return col.Width ?? ((col.Text.Length * _charSize.Width) + (CellPadding * 4));
2014-08-08 18:30:57 +00:00
}
#endregion
}
public class RollColumns : List<RollColumn>
{
2014-08-07 23:10:41 +00:00
public void Add(string name, string text, int width, RollColumn.InputType type = RollColumn.InputType.Text)
{
Add(new RollColumn
{
Name = name,
Text = text,
2014-08-07 18:32:09 +00:00
Width = width,
Type = type
});
}
2014-08-09 16:11:25 +00:00
public IEnumerable<string> Groups
{
get
{
return this
.Select(x => x.Group)
.Distinct();
}
}
}
public class RollColumn
{
2014-08-09 16:11:25 +00:00
public enum InputType { Boolean, Float, Text, Image }
2014-08-07 18:32:09 +00:00
2014-08-09 16:11:25 +00:00
public string Group { get; set; }
public int? Width { get; set; }
public string Name { get; set; }
public string Text { get; set; }
2014-08-07 18:32:09 +00:00
public InputType Type { get; set; }
}
}