2017-06-20 07:12:13 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
2017-07-14 04:48:37 +00:00
|
|
|
|
using NLua;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
|
|
|
{
|
|
|
|
|
public class LuaPictureBox : PictureBox
|
|
|
|
|
{
|
|
|
|
|
#region Helpers
|
|
|
|
|
private readonly Dictionary<string, Image> _imageCache = new Dictionary<string, Image>();
|
|
|
|
|
|
|
|
|
|
private readonly Dictionary<Color, SolidBrush> _solidBrushes = new Dictionary<Color, SolidBrush>();
|
|
|
|
|
private readonly Dictionary<Color, Pen> _pens = new Dictionary<Color, Pen>();
|
|
|
|
|
|
|
|
|
|
private SolidBrush GetBrush(Color color)
|
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
if (!_solidBrushes.TryGetValue(color, out var b))
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
b = new SolidBrush(color);
|
|
|
|
|
_solidBrushes[color] = b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Pen GetPen(Color color)
|
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
if (!_pens.TryGetValue(color, out var p))
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
p = new Pen(color);
|
|
|
|
|
_pens[color] = p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
private Color _defaultForeground = Color.Black;
|
|
|
|
|
private Color? _defaultBackground;
|
|
|
|
|
private Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
public LuaPictureBox()
|
|
|
|
|
{
|
|
|
|
|
Image = new Bitmap(Width, Height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void LuaResize(int width, int height)
|
|
|
|
|
{
|
|
|
|
|
Width = width;
|
|
|
|
|
Height = height;
|
|
|
|
|
Image = new Bitmap(width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear(Color color)
|
|
|
|
|
{
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.Clear(color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetDefaultForegroundColor(Color color)
|
|
|
|
|
{
|
|
|
|
|
_defaultForeground = color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetDefaultBackgroundColor(Color color)
|
|
|
|
|
{
|
|
|
|
|
_defaultBackground = color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetDefaultTextBackground(Color color)
|
|
|
|
|
{
|
|
|
|
|
_defaultTextBackground = color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawBezier(LuaTable points, Color color)
|
|
|
|
|
{
|
|
|
|
|
var pointsArr = new Point[4];
|
|
|
|
|
|
|
|
|
|
var i = 0;
|
|
|
|
|
foreach (LuaTable point in points.Values)
|
|
|
|
|
{
|
|
|
|
|
pointsArr[i] = new Point((int)(double)(point[1]), (int)(double)(point[2]));
|
|
|
|
|
i++;
|
|
|
|
|
if (i >= 4)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawBezier(GetPen(color), pointsArr[0], pointsArr[1], pointsArr[2], pointsArr[3]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? background = null)
|
|
|
|
|
{
|
|
|
|
|
if (x < x2)
|
|
|
|
|
{
|
|
|
|
|
x2 = Math.Abs(x - x2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
x2 = x - x2;
|
|
|
|
|
x -= x2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (y < y2)
|
|
|
|
|
{
|
|
|
|
|
y2 = Math.Abs(y - y2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
y2 = y - y2;
|
|
|
|
|
y -= y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, x2, y2);
|
|
|
|
|
|
|
|
|
|
var bg = background ?? _defaultBackground;
|
|
|
|
|
if (bg.HasValue)
|
|
|
|
|
{
|
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, x2 - 1, y2 - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawEllipse(int x, int y, int width, int height, Color? line = null, Color? background = null)
|
|
|
|
|
{
|
|
|
|
|
var bg = background ?? _defaultBackground;
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
if (bg.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var brush = GetBrush(bg.Value);
|
|
|
|
|
boxBackground.FillEllipse(brush, x, y, width, height);
|
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boxBackground.DrawEllipse(GetPen(line ?? _defaultForeground), x, y, width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawIcon(string path, int x, int y, int? width = null, int? height = null)
|
|
|
|
|
{
|
|
|
|
|
Icon icon;
|
|
|
|
|
if (width.HasValue && height.HasValue)
|
|
|
|
|
{
|
|
|
|
|
icon = new Icon(path, width.Value, height.Value);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
icon = new Icon(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawIcon(icon, x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawImage(string path, int x, int y, int? width = null, int? height = null, bool cache = true)
|
|
|
|
|
{
|
|
|
|
|
Image img;
|
|
|
|
|
if (_imageCache.ContainsKey(path))
|
|
|
|
|
{
|
|
|
|
|
img = _imageCache[path];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
img = Image.FromFile(path);
|
|
|
|
|
if (cache)
|
|
|
|
|
{
|
|
|
|
|
_imageCache.Add(path, img);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawImage(img, x, y, width ?? img.Width, height ?? img.Height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearImageCache()
|
|
|
|
|
{
|
|
|
|
|
foreach (var image in _imageCache)
|
|
|
|
|
{
|
|
|
|
|
image.Value.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_imageCache.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
public void DrawImageRegion(string path, int sourceX, int sourceY, int sourceWidth, int sourceHeight, int destX, int destY, int? destWidth = null, int? destHeight = null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
Image img;
|
|
|
|
|
if (_imageCache.ContainsKey(path))
|
|
|
|
|
{
|
|
|
|
|
img = _imageCache[path];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
img = Image.FromFile(path);
|
|
|
|
|
_imageCache.Add(path, img);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
var destRect = new Rectangle(destX, destY, destWidth ?? sourceWidth, destHeight ?? sourceHeight);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.DrawImage(img, destRect, sourceX, sourceY, sourceWidth, sourceHeight, GraphicsUnit.Pixel);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawLine(int x1, int y1, int x2, int y2, Color? color = null)
|
|
|
|
|
{
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawLine(GetPen(color ?? _defaultForeground), x1, y1, x2, y2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawAxis(int x, int y, int size, Color? color = null)
|
|
|
|
|
{
|
|
|
|
|
DrawLine(x + size, y, x - size, y, color);
|
|
|
|
|
DrawLine(x, y + size, x, y - size, color);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
public void DrawArc(int x, int y, int width, int height, int startAngle, int sweepAngle, Color? line = null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.DrawArc(GetPen(line ?? _defaultForeground), x, y, width, height, startAngle, sweepAngle);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawPie(
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
2019-11-30 17:28:56 +00:00
|
|
|
|
int startAngle,
|
|
|
|
|
int sweepAngle,
|
2017-06-20 07:12:13 +00:00
|
|
|
|
Color? line = null,
|
|
|
|
|
Color? background = null)
|
|
|
|
|
{
|
|
|
|
|
var bg = background ?? _defaultBackground;
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
if (bg.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var brush = GetBrush(bg.Value);
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.FillPie(brush, x, y, width, height, startAngle, sweepAngle);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.DrawPie(GetPen(line ?? _defaultForeground), x + 1, y + 1, width - 1, height - 1, startAngle, sweepAngle);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawPixel(int x, int y, Color? color = null)
|
|
|
|
|
{
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawLine(GetPen(color ?? _defaultForeground), x, y, x + 0.1F, y);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-16 20:44:18 +00:00
|
|
|
|
public void DrawPolygon(LuaTable points, int? x = null, int? y = null, Color? line = null, Color? background = null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
var pointsArr = new Point[points.Values.Count];
|
|
|
|
|
var i = 0;
|
|
|
|
|
foreach (LuaTable point in points.Values)
|
|
|
|
|
{
|
2018-04-16 20:44:18 +00:00
|
|
|
|
pointsArr[i] = new Point((int)(double)(point[1]) + x ?? 0, (int)(double)(point[2]) + y ?? 0);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.DrawPolygon(GetPen(line ?? _defaultForeground), pointsArr);
|
|
|
|
|
var bg = background ?? _defaultBackground;
|
|
|
|
|
if (bg.HasValue)
|
|
|
|
|
{
|
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.FillPolygon(GetBrush(bg.Value), pointsArr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawRectangle(int x, int y, int width, int height, Color? line = null, Color? background = null)
|
|
|
|
|
{
|
|
|
|
|
var bg = background ?? _defaultBackground;
|
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
if (bg.HasValue)
|
|
|
|
|
{
|
|
|
|
|
boxBackground.FillRectangle(GetBrush(bg.Value), x, y, width, height);
|
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boxBackground.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DrawText(
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
string message,
|
2019-11-30 17:28:56 +00:00
|
|
|
|
Color? foreColor = null,
|
|
|
|
|
Color? backColor = null,
|
|
|
|
|
int? fontSize = null,
|
|
|
|
|
string fontFamily = null,
|
|
|
|
|
string fontStyle = null,
|
|
|
|
|
string horizAlign = null,
|
|
|
|
|
string vertAlign = null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
var family = FontFamily.GenericMonospace;
|
2019-11-30 17:28:56 +00:00
|
|
|
|
if (fontFamily != null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
family = new FontFamily(fontFamily);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
var fStyle = FontStyle.Regular;
|
|
|
|
|
if (fontStyle != null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
switch (fontStyle.ToLower())
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case "regular":
|
|
|
|
|
break;
|
|
|
|
|
case "bold":
|
2019-11-30 17:28:56 +00:00
|
|
|
|
fStyle = FontStyle.Bold;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
|
|
|
|
case "italic":
|
2019-11-30 17:28:56 +00:00
|
|
|
|
fStyle = FontStyle.Italic;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
|
|
|
|
case "strikethrough":
|
2019-11-30 17:28:56 +00:00
|
|
|
|
fStyle = FontStyle.Strikeout;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
|
|
|
|
case "underline":
|
2019-11-30 17:28:56 +00:00
|
|
|
|
fStyle = FontStyle.Underline;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var f = new StringFormat(StringFormat.GenericDefault);
|
2019-11-30 17:28:56 +00:00
|
|
|
|
var font = new Font(family, fontSize ?? 12, fStyle, GraphicsUnit.Pixel);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
var boxBackground = Graphics.FromImage(Image);
|
2019-10-29 13:23:40 +00:00
|
|
|
|
|
|
|
|
|
Size sizeOfText = boxBackground.MeasureString(message, font, 0, f).ToSize();
|
2017-06-20 07:12:13 +00:00
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
if (horizAlign != null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
switch (horizAlign.ToLower())
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case "left":
|
|
|
|
|
break;
|
|
|
|
|
case "center":
|
2018-09-14 21:16:35 +00:00
|
|
|
|
case "middle":
|
2017-06-20 07:12:13 +00:00
|
|
|
|
x -= sizeOfText.Width / 2;
|
|
|
|
|
break;
|
|
|
|
|
case "right":
|
2018-09-10 08:27:29 +00:00
|
|
|
|
x -= sizeOfText.Width;
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-30 17:28:56 +00:00
|
|
|
|
if (vertAlign != null)
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
switch (vertAlign.ToLower())
|
2017-06-20 07:12:13 +00:00
|
|
|
|
{
|
|
|
|
|
default:
|
2018-09-14 21:16:35 +00:00
|
|
|
|
case "top":
|
2017-06-20 07:12:13 +00:00
|
|
|
|
break;
|
2018-09-14 21:16:35 +00:00
|
|
|
|
case "center":
|
2017-06-20 07:12:13 +00:00
|
|
|
|
case "middle":
|
|
|
|
|
y -= sizeOfText.Height / 2;
|
|
|
|
|
break;
|
2018-09-14 21:16:35 +00:00
|
|
|
|
case "bottom":
|
2017-06-20 07:12:13 +00:00
|
|
|
|
y -= sizeOfText.Height;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Rectangle rect = new Rectangle(new Point(x, y), sizeOfText);
|
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.FillRectangle(GetBrush(backColor ?? _defaultTextBackground.Value), rect);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
boxBackground = Graphics.FromImage(Image);
|
|
|
|
|
boxBackground.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
|
2019-11-30 17:28:56 +00:00
|
|
|
|
boxBackground.DrawString(message, font, new SolidBrush(foreColor ?? Color.Black), x, y);
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
2017-06-30 01:52:40 +00:00
|
|
|
|
|
|
|
|
|
public Point GetMouse()
|
|
|
|
|
{
|
2019-11-30 17:28:56 +00:00
|
|
|
|
var p = PointToClient(MousePosition);
|
2017-06-30 01:52:40 +00:00
|
|
|
|
return p;
|
|
|
|
|
}
|
2017-07-14 04:48:37 +00:00
|
|
|
|
|
|
|
|
|
private void DoLuaClick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
LuaWinform parent = Parent as LuaWinform;
|
|
|
|
|
parent?.DoLuaEvent(Handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnClick(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
DoLuaClick(this, e);
|
|
|
|
|
base.OnClick(e);
|
|
|
|
|
}
|
2017-06-20 07:12:13 +00:00
|
|
|
|
}
|
2018-04-16 20:15:37 +00:00
|
|
|
|
}
|