Port InputRoll by adding GDI+ implementation
also available for Windows users via a toggle in TAStudio
This commit is contained in:
parent
881974b495
commit
d0159ee565
BizHawk.Client.Common/config
BizHawk.Client.EmuHawk
|
@ -509,6 +509,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
// TAStudio
|
||||
public TasStateManagerSettings DefaultTasProjSettings = new TasStateManagerSettings();
|
||||
/// <remarks>defaults to 0 (GDI) - on linux this is forced to GDI+ later on</remarks>
|
||||
public int TasStudioRenderer = 0;
|
||||
|
||||
// Macro Tool
|
||||
public RecentFiles RecentMacros = new RecentFiles(8);
|
||||
|
|
|
@ -592,6 +592,14 @@
|
|||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.Drawing.GDI.cs">
|
||||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.Drawing.GDIP.cs">
|
||||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\MenuButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,433 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.EmuHawk.CustomControls;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <remarks>GDI32.dll related methods are abstracted to here</remarks>
|
||||
public partial class InputRoll
|
||||
{
|
||||
private readonly GDIRenderer _gdi;
|
||||
private readonly IntPtr _rotatedFont;
|
||||
private readonly IntPtr _normalFont;
|
||||
private Size _charSize;
|
||||
|
||||
#region Initialization and Destruction
|
||||
|
||||
/// <summary>Initialises GDI-related stuff (called from constructor)</summary>
|
||||
private void GDIConstruction()
|
||||
{
|
||||
using (var g = CreateGraphics()) using (_gdi.LockGraphics(g))
|
||||
_charSize = _gdi.MeasureString("A", _commonFont); //TODO make this a property so changing it updates other values
|
||||
}
|
||||
|
||||
private void GDIDispose()
|
||||
{
|
||||
_gdi.Dispose();
|
||||
GDIRenderer.DestroyHFont(_normalFont);
|
||||
GDIRenderer.DestroyHFont(_rotatedFont);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Drawing Methods Using GDI
|
||||
|
||||
private void GDI_OnPaint(PaintEventArgs e)
|
||||
{
|
||||
using (_gdi.LockGraphics(e.Graphics))
|
||||
{
|
||||
_gdi.StartOffScreenBitmap(Width, Height);
|
||||
|
||||
// White Background
|
||||
_gdi.SetBrush(Color.White);
|
||||
_gdi.SetSolidPen(Color.White);
|
||||
_gdi.FillRectangle(0, 0, Width, Height);
|
||||
|
||||
// Lag frame calculations
|
||||
SetLagFramesArray();
|
||||
|
||||
var visibleColumns = _columns.VisibleColumns.ToList();
|
||||
|
||||
if (visibleColumns.Count != 0)
|
||||
{
|
||||
DrawColumnBg(e, visibleColumns);
|
||||
DrawColumnText(e, visibleColumns);
|
||||
}
|
||||
|
||||
// Background
|
||||
DrawBg(e, visibleColumns);
|
||||
|
||||
// Foreground
|
||||
DrawData(e, visibleColumns);
|
||||
|
||||
DrawColumnDrag(e);
|
||||
DrawCellDrag(e);
|
||||
|
||||
_gdi.CopyToScreen();
|
||||
_gdi.EndOffScreenBitmap();
|
||||
}
|
||||
}
|
||||
|
||||
private void GDI_DrawColumnDrag()
|
||||
{
|
||||
if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
|
||||
{
|
||||
var x1 = _currentX.Value - _columnDown.Width.Value / 2;
|
||||
var y1 = _currentY.Value - CellHeight / 2;
|
||||
var x2 = x1 + _columnDown.Width.Value;
|
||||
var y2 = y1 + CellHeight;
|
||||
|
||||
_gdi.SetSolidPen(_backColor);
|
||||
_gdi.DrawRectangle(x1, y1, x2, y2);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
_gdi.DrawString(_columnDown.Text, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding));
|
||||
}
|
||||
}
|
||||
|
||||
private void GDI_DrawCellDrag()
|
||||
{
|
||||
if (_draggingCell == null) return;
|
||||
|
||||
var rowIndex = _draggingCell.RowIndex.Value;
|
||||
var column = _draggingCell.Column;
|
||||
var text = "";
|
||||
var offsetX = 0;
|
||||
var offsetY = 0;
|
||||
QueryItemText?.Invoke(rowIndex, column, out text, ref offsetX, ref offsetY);
|
||||
|
||||
var bgColor = _backColor;
|
||||
QueryItemBkColor?.Invoke(rowIndex, column, ref bgColor);
|
||||
|
||||
var draggedWidth = column.Width.Value;
|
||||
var draggedHeight = CellHeight;
|
||||
var x1 = _currentX.Value - draggedWidth / 2;
|
||||
var y1 = _currentY.Value - draggedHeight / 2;
|
||||
|
||||
_gdi.SetBrush(bgColor);
|
||||
_gdi.FillRectangle(x1, y1, draggedWidth, draggedHeight);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
_gdi.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
|
||||
}
|
||||
|
||||
private void GDI_DrawColumnText(IEnumerable<RollColumn> visibleColumns)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
var isHoveringOnColumnCell = IsHoveringOnColumnCell;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
var start = -_vBar.Value;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(CellWidthPadding, start + CellHeightPadding);
|
||||
if (isHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
_gdi.DrawString(column.Text, point);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.DrawString(column.Text, point);
|
||||
}
|
||||
start += CellHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var paddingX = 2 * CellWidthPadding - _hBar.Value; //TODO fix this CellPadding issue (2 * CellPadding vs just CellPadding)
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(column.Left.Value + paddingX, CellHeightPadding);
|
||||
if (isHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
_gdi.DrawString(column.Text, point);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.DrawString(column.Text, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDI_DrawData(IReadOnlyList<RollColumn> visibleColumns)
|
||||
{
|
||||
if (visibleColumns.Count == 0) return; // Prevent exceptions with small TAStudio windows
|
||||
if (QueryItemText == null) return;
|
||||
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
|
||||
var startRow = FirstVisibleRow;
|
||||
var range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
int LastVisible;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (int i = 0, f = 0; f < range; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
LastVisible = LastVisibleColumnIndex;
|
||||
for (var j = FirstVisibleColumn; j <= LastVisible; j++)
|
||||
{
|
||||
Bitmap image = null;
|
||||
var bitmapOffsetX = 0;
|
||||
var bitmapOffsetY = 0;
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
_gdi.DrawBitmap(
|
||||
image,
|
||||
new Point(RowsToPixels(i) + CellWidthPadding + bitmapOffsetX, j * CellHeight + CellHeightPadding * 2 + bitmapOffsetY),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
string text;
|
||||
var strOffsetX = 0;
|
||||
var strOffsetY = 0;
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
var rePrep = j == 1;
|
||||
if (rePrep)
|
||||
{
|
||||
// 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
|
||||
_gdi.PrepDrawString(
|
||||
_rotatedFont,
|
||||
_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow })
|
||||
? SystemColors.HighlightText
|
||||
: _foreColor
|
||||
);
|
||||
}
|
||||
|
||||
// Centre Text
|
||||
var point = new Point(
|
||||
RowsToPixels(i) + (CellWidth - text.Length * _charSize.Width) / 2 + strOffsetX,
|
||||
j * CellHeight + CellHeightPadding - _vBar.Value + strOffsetY
|
||||
);
|
||||
if (!string.IsNullOrWhiteSpace(text)) _gdi.DrawString(text, point);
|
||||
|
||||
if (rePrep) _gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var xPadding = CellWidthPadding + 1 - _hBar.Value;
|
||||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
LastVisible = LastVisibleColumnIndex;
|
||||
var y = RowsToPixels(i) + CellHeightPadding;
|
||||
for (var j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
|
||||
{
|
||||
var column = visibleColumns[j];
|
||||
var x = column.Left.Value + xPadding;
|
||||
Bitmap image = null;
|
||||
var bitmapOffsetX = 0;
|
||||
var bitmapOffsetY = 0;
|
||||
QueryItemIcon?.Invoke(f + startRow, column, ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
_gdi.DrawBitmap(
|
||||
image,
|
||||
new Point(x + bitmapOffsetX, y + bitmapOffsetY + CellHeightPadding),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
string text;
|
||||
var strOffsetX = 0;
|
||||
var strOffsetY = 0;
|
||||
QueryItemText(f + startRow, column, out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
var rePrep = !_selectedItems.Contains(new Cell { Column = column, RowIndex = f + startRow });
|
||||
|
||||
if (rePrep) _gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text)) _gdi.DrawString(text, new Point(x + strOffsetX, y + strOffsetY));
|
||||
|
||||
if (rePrep) _gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDI_DrawColumnBg(IReadOnlyList<RollColumn> visibleColumns)
|
||||
{
|
||||
var columnCount = visibleColumns.Count;
|
||||
|
||||
_gdi.SetBrush(SystemColors.ControlLight);
|
||||
_gdi.SetSolidPen(Color.Black);
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
_gdi.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
|
||||
_gdi.Line(0, 0, 0, columnCount * CellHeight + 1);
|
||||
_gdi.Line(ColumnWidth, 0, ColumnWidth, columnCount * CellHeight + 1);
|
||||
|
||||
if (columnCount != 0) for (int i = 0, y = -_vBar.Value; i <= columnCount; i++, y += CellHeight)
|
||||
{
|
||||
_gdi.Line(1, y, ColumnWidth, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var bottomEdge = RowsToPixels(0);
|
||||
|
||||
// Gray column box and black line underneath
|
||||
_gdi.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
|
||||
_gdi.Line(0, 0, TotalColWidth.Value + 1, 0);
|
||||
_gdi.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
|
||||
|
||||
// Vertical black seperators
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var x = column.Left.Value - _hBar.Value;
|
||||
_gdi.Line(x, 0, x, bottomEdge);
|
||||
}
|
||||
if (columnCount != 0)
|
||||
{
|
||||
var x = TotalColWidth.Value - _hBar.Value;
|
||||
_gdi.Line(x, 0, x, bottomEdge);
|
||||
}
|
||||
}
|
||||
|
||||
// Emphasis
|
||||
var columnHeight = ColumnHeight - 1;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (var i = 0; i < columnCount; i++)
|
||||
{
|
||||
if (!visibleColumns[i].Emphasis) continue; // only act on emphasised columns
|
||||
|
||||
_gdi.SetBrush(SystemColors.ActiveBorder);
|
||||
_gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, columnHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
if (!column.Emphasis) continue; // only act on emphasised columns
|
||||
|
||||
_gdi.SetBrush(SystemColors.ActiveBorder);
|
||||
_gdi.FillRectangle(column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, columnHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user is hovering over a column
|
||||
if (IsHoveringOnColumnCell)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (var i = 0; i < columnCount; i++)
|
||||
{
|
||||
var column = visibleColumns[i];
|
||||
if (column != CurrentCell.Column) continue; // only act on selected
|
||||
|
||||
_gdi.SetBrush(column.Emphasis ? Add(SystemColors.Highlight, 0x00222222) : SystemColors.Highlight);
|
||||
_gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, columnHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO multiple selected columns
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
if (column != CurrentCell.Column) continue; // only act on selected
|
||||
if (column.Left.Value - _hBar.Value > Width || column.Right.Value - _hBar.Value < 0) continue; // Left of column is to the right of the viewable area, or right of column is to the left of the viewable area
|
||||
|
||||
_gdi.SetBrush(column.Emphasis ? Add(SystemColors.Highlight, 0x00550000) : SystemColors.Highlight);
|
||||
var left = column.Left.Value + 1;
|
||||
_gdi.FillRectangle(left - _hBar.Value, 1, column.Right.Value - left, columnHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDI_DrawBg(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (UseCustomBackground && QueryItemBkColor != null) DoBackGroundCallback(e, visibleColumns);
|
||||
|
||||
if (GridLines)
|
||||
{
|
||||
_gdi.SetSolidPen(SystemColors.ControlLight);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
// Columns
|
||||
var iLimit = VisibleRows + 1;
|
||||
for (var i = 1; i < iLimit; i++)
|
||||
{
|
||||
var x = RowsToPixels(i);
|
||||
_gdi.Line(x, 1, x, DrawHeight);
|
||||
}
|
||||
|
||||
// Rows
|
||||
var x1 = RowsToPixels(0) + 1;
|
||||
var jLimit = visibleColumns.Count + 1;
|
||||
for (var j = 0; j < jLimit; j++) _gdi.Line(x1, j * CellHeight - _vBar.Value, DrawWidth, j * CellHeight - _vBar.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Columns
|
||||
var y1 = ColumnHeight + 1;
|
||||
var y2 = Height - 1;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var x = column.Left.Value - _hBar.Value;
|
||||
_gdi.Line(x, y1, x, y2);
|
||||
}
|
||||
if (visibleColumns.Count != 0)
|
||||
{
|
||||
var x = TotalColWidth.Value - _hBar.Value;
|
||||
_gdi.Line(x, y1, x, y2);
|
||||
}
|
||||
|
||||
// Rows
|
||||
var x2 = Width + 1;
|
||||
var iLimit = VisibleRows + 1;
|
||||
for (var i = 1; i < iLimit; i++)
|
||||
{
|
||||
var y = RowsToPixels(i);
|
||||
_gdi.Line(0, y, x2, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedItems.Count != 0) DoSelectionBG(e, visibleColumns);
|
||||
}
|
||||
|
||||
private void GDI_DrawCellBG(Color color, Cell cell, IList<RollColumn> visibleColumns)
|
||||
{
|
||||
// We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
int x, y, w;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
x = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
if (x < ColumnWidth) return;
|
||||
y = CellHeight * visibleColumns.IndexOf(cell.Column) + 1 - _vBar.Value;
|
||||
w = CellWidth - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
if (y < ColumnHeight) return;
|
||||
x = cell.Column.Left.Value - _hBar.Value + 1;
|
||||
w = cell.Column.Width.Value - 1;
|
||||
}
|
||||
if (x > DrawWidth || y > DrawHeight) return; // Don't draw if off-screen.
|
||||
|
||||
_gdi.SetBrush(color);
|
||||
_gdi.FillRectangle(x, y, w, CellHeight - 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,477 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <remarks>New GDI+ methods live here</remarks>
|
||||
public partial class InputRoll
|
||||
{
|
||||
/// <remarks>instance field to mirror GDI implementation</remarks>
|
||||
private Pen sPen;
|
||||
|
||||
/// <remarks>instance field to mirror GDI implementation</remarks>
|
||||
private Brush sBrush;
|
||||
|
||||
/// <remarks>GDI+ uses floats to measure strings</remarks>
|
||||
private SizeF _charSizeF;
|
||||
|
||||
#region Initialization and Destruction
|
||||
|
||||
/// <summary>Initialises GDI+-related stuff (called from constructor)</summary>
|
||||
private void GDIPConstruction()
|
||||
{
|
||||
// HFont?
|
||||
// Rotated HFont?
|
||||
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
SetStyle(ControlStyles.Opaque, true);
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
||||
|
||||
using (var g = CreateGraphics())
|
||||
{
|
||||
_charSizeF = g.MeasureString("A", _commonFont);
|
||||
// _charSize = Size.Round(sizeF);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Drawing Methods Using GDI+
|
||||
|
||||
private void GDIP_OnPaint(PaintEventArgs e)
|
||||
{
|
||||
// white background
|
||||
sBrush = new SolidBrush(Color.White);
|
||||
sPen = new Pen(Color.White);
|
||||
|
||||
e.Graphics.FillRectangle(sBrush, e.ClipRectangle);
|
||||
e.Graphics.Flush();
|
||||
|
||||
// Lag frame calculations
|
||||
SetLagFramesArray();
|
||||
|
||||
var visibleColumns = _columns.VisibleColumns.ToList();
|
||||
|
||||
if (visibleColumns.Count != 0)
|
||||
{
|
||||
DrawColumnBg(e, visibleColumns);
|
||||
DrawColumnText(e, visibleColumns);
|
||||
}
|
||||
|
||||
// Background
|
||||
DrawBg(e, visibleColumns);
|
||||
|
||||
// Foreground
|
||||
DrawData(e, visibleColumns);
|
||||
|
||||
DrawColumnDrag(e);
|
||||
DrawCellDrag(e);
|
||||
}
|
||||
|
||||
private void GDIP_DrawColumnDrag(PaintEventArgs e)
|
||||
{
|
||||
if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
|
||||
{
|
||||
var x1 = _currentX.Value - _columnDown.Width.Value / 2;
|
||||
var y1 = _currentY.Value - CellHeight / 2;
|
||||
var x2 = x1 + _columnDown.Width.Value;
|
||||
var y2 = y1 + CellHeight;
|
||||
|
||||
sPen = new Pen(_backColor);
|
||||
e.Graphics.DrawRectangle(sPen, x1, y1, x2, y2);
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
// e.Graphics.DrawString(_columnDown.Text, _commonFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding, y1 + CellHeightPadding)));
|
||||
GDIP_DrawString(e, _columnDown.Text, _commonFont, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding), _foreColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void GDIP_DrawCellDrag(PaintEventArgs e)
|
||||
{
|
||||
if (_draggingCell == null) return;
|
||||
|
||||
var text = "";
|
||||
var offsetX = 0;
|
||||
var offsetY = 0;
|
||||
QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY);
|
||||
|
||||
var bgColor = _backColor;
|
||||
QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor);
|
||||
|
||||
var x1 = _currentX.Value - _draggingCell.Column.Width.Value / 2;
|
||||
var y1 = _currentY.Value - CellHeight / 2;
|
||||
var x2 = x1 + _draggingCell.Column.Width.Value;
|
||||
var y2 = y1 + CellHeight;
|
||||
|
||||
sBrush = new SolidBrush(bgColor);
|
||||
e.Graphics.FillRectangle(sBrush, x1, y1, x2 - x1, y2 - y1);
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)(new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY)));
|
||||
GDIP_DrawString(e, text, _commonFont, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY), _foreColor);
|
||||
}
|
||||
|
||||
private void GDIP_DrawColumnText(PaintEventArgs e, IReadOnlyCollection<RollColumn> visibleColumns)
|
||||
{
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
var start = -_vBar.Value;
|
||||
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(CellWidthPadding, start + CellHeightPadding);
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
var temp = sBrush;
|
||||
sBrush = new SolidBrush(SystemColors.HighlightText);
|
||||
// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
|
||||
GDIP_DrawString(e, column.Text, _commonFont, point, SystemColors.HighlightText);
|
||||
sBrush = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
|
||||
GDIP_DrawString(e, column.Text, _commonFont, point, _foreColor);
|
||||
}
|
||||
|
||||
start += CellHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var xPadding = CellWidthPadding + 1 - _hBar.Value;
|
||||
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(column.Left.Value + xPadding, CellHeightPadding);
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
var temp = sBrush;
|
||||
sBrush = new SolidBrush(SystemColors.HighlightText);
|
||||
// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
|
||||
GDIP_DrawString(e, column.Text, _commonFont, point, SystemColors.HighlightText);
|
||||
sBrush = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// e.Graphics.DrawString(column.Text, _commonFont, sBrush, (PointF)(point));
|
||||
GDIP_DrawString(e, column.Text, _commonFont, point, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDIP_DrawData(PaintEventArgs e, IReadOnlyList<RollColumn> visibleColumns)
|
||||
{
|
||||
if (visibleColumns.Count == 0) return; // Prevent exceptions with small TAStudio windows
|
||||
if (QueryItemText == null) return;
|
||||
|
||||
var startRow = FirstVisibleRow;
|
||||
int LastVisible;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
var isRotated = false;
|
||||
var fLimit = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
for (int i = 0, f = 0; f < fLimit; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
LastVisible = LastVisibleColumnIndex;
|
||||
for (var j = FirstVisibleColumn; j <= LastVisible; j++)
|
||||
{
|
||||
Bitmap image = null;
|
||||
var bitmapOffsetX = 0;
|
||||
var bitmapOffsetY = 0;
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
var x1 = RowsToPixels(i) + CellWidthPadding + bitmapOffsetX;
|
||||
var y1 = j * CellHeight + CellHeightPadding * 2 + bitmapOffsetY;
|
||||
e.Graphics.DrawImage(image, new Point(x1, y1));
|
||||
}
|
||||
|
||||
string text;
|
||||
var strOffsetX = 0;
|
||||
var strOffsetY = 0;
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
// Centre Text
|
||||
var point = new Point(
|
||||
RowsToPixels(i) + (CellWidth - (int)Math.Round(text.Length * _charSizeF.Width)) / 2 + strOffsetX,
|
||||
j * CellHeight + CellHeightPadding - _vBar.Value + strOffsetY
|
||||
);
|
||||
|
||||
var rePrep = false;
|
||||
if (j == 1)
|
||||
{
|
||||
if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow }))
|
||||
{
|
||||
isRotated = true;
|
||||
sBrush = new SolidBrush(SystemColors.HighlightText);
|
||||
rePrep = true;
|
||||
}
|
||||
else if (j == 1)
|
||||
{
|
||||
// 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
|
||||
rePrep = true;
|
||||
isRotated = true;
|
||||
sBrush = new SolidBrush(SystemColors.HighlightText);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
// _gdi.DrawString(text, point);
|
||||
if (isRotated)
|
||||
{
|
||||
var sz = e.Graphics.VisibleClipBounds.Size;
|
||||
e.Graphics.TranslateTransform(sz.Width / 2, sz.Height / 2);
|
||||
e.Graphics.RotateTransform(90);
|
||||
sz = e.Graphics.MeasureString(text, _commonFont);
|
||||
e.Graphics.DrawString(text, _commonFont, sBrush, -(sz.Width / 2), -(sz.Height / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)point);
|
||||
GDIP_DrawString(e, text, _commonFont, point, new Pen(sBrush).Color);
|
||||
}
|
||||
}
|
||||
|
||||
if (rePrep)
|
||||
{
|
||||
isRotated = false;
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
var xPadding = CellWidthPadding + 1 - _hBar.Value;
|
||||
sBrush = new SolidBrush(_foreColor);
|
||||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
LastVisible = LastVisibleColumnIndex;
|
||||
for (var j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
|
||||
{
|
||||
var col = visibleColumns[j];
|
||||
|
||||
Bitmap image = null;
|
||||
var bitmapOffsetX = 0;
|
||||
var bitmapOffsetY = 0;
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
var point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding);
|
||||
if (image != null) e.Graphics.DrawImage(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding));
|
||||
|
||||
string text;
|
||||
var strOffsetX = 0;
|
||||
var strOffsetY = 0;
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
var rePrep = false;
|
||||
if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow }))
|
||||
{
|
||||
sBrush = new SolidBrush(SystemColors.HighlightText);
|
||||
rePrep = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
// e.Graphics.DrawString(text, _commonFont, sBrush, (PointF)(new Point(point.X + strOffsetX, point.Y + strOffsetY)));
|
||||
GDIP_DrawString(e, text, _commonFont, new Point(point.X + strOffsetX, point.Y + strOffsetY), new Pen(sBrush).Color);
|
||||
}
|
||||
|
||||
if (rePrep) sBrush = new SolidBrush(_foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDIP_DrawColumnBg(PaintEventArgs e, IReadOnlyList<RollColumn> visibleColumns)
|
||||
{
|
||||
var columnCount = visibleColumns.Count;
|
||||
sBrush = new SolidBrush(SystemColors.ControlLight);
|
||||
sPen = new Pen(Color.Black);
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
e.Graphics.FillRectangle(sBrush, 0, 0, ColumnWidth + 1, DrawHeight + 1);
|
||||
e.Graphics.DrawLine(sPen, 0, 0, 0, columnCount * CellHeight + 1);
|
||||
e.Graphics.DrawLine(sPen, ColumnWidth, 0, ColumnWidth, columnCount * CellHeight + 1);
|
||||
|
||||
var iLimit = columnCount + 1;
|
||||
if (iLimit > 1)
|
||||
{
|
||||
for (int i = 0, y = -_vBar.Value; i < iLimit; i++, y += CellHeight) e.Graphics.DrawLine(sPen, 1, y, ColumnWidth, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var bottomEdge = RowsToPixels(0);
|
||||
|
||||
// Gray column box and black line underneath
|
||||
e.Graphics.FillRectangle(sBrush, 0, 0, Width + 1, bottomEdge + 1);
|
||||
e.Graphics.DrawLine(sPen, 0, 0, TotalColWidth.Value + 1, 0);
|
||||
e.Graphics.DrawLine(sPen, 0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
|
||||
|
||||
// Vertical black seperators
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var pos = column.Left.Value - _hBar.Value;
|
||||
e.Graphics.DrawLine(sPen, pos, 0, pos, bottomEdge);
|
||||
}
|
||||
if (columnCount != 0)
|
||||
{
|
||||
var right = TotalColWidth.Value - _hBar.Value;
|
||||
e.Graphics.DrawLine(sPen, right, 0, right, bottomEdge);
|
||||
}
|
||||
}
|
||||
|
||||
// Emphasis
|
||||
for (var i = 0; i < columnCount; i++)
|
||||
{
|
||||
var column = visibleColumns[i];
|
||||
if (!column.Emphasis) continue; // only act on emphasised columns
|
||||
|
||||
sBrush = new SolidBrush(SystemColors.ActiveBorder);
|
||||
if (HorizontalOrientation) e.Graphics.FillRectangle(sBrush, 1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
|
||||
else e.Graphics.FillRectangle(sBrush, column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
|
||||
}
|
||||
|
||||
// If the user is hovering over a column
|
||||
if (IsHoveringOnColumnCell)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (var i = 0; i < columnCount; i++)
|
||||
{
|
||||
var column = visibleColumns[i];
|
||||
if (column != CurrentCell.Column) continue; // only act on selected
|
||||
|
||||
sBrush = new SolidBrush(column.Emphasis
|
||||
? Color.FromArgb(SystemColors.Highlight.ToArgb() + 0x00222222) //TODO should be bitwise or?
|
||||
: SystemColors.Highlight);
|
||||
|
||||
e.Graphics.FillRectangle(sBrush, 1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO multiple selected columns
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
if (column != CurrentCell.Column) continue; // only act on selected
|
||||
if (column.Left.Value - _hBar.Value > Width || column.Right.Value - _hBar.Value < 0) continue; // Left of column is to the right of the viewable area, or right of column is to the left of the viewable area
|
||||
|
||||
var left = column.Left.Value - _hBar.Value;
|
||||
var width = column.Right.Value - _hBar.Value - left;
|
||||
sBrush = new SolidBrush(column.Emphasis
|
||||
? Color.FromArgb(SystemColors.Highlight.ToArgb() + 0x00550000) //TODO should be bitwise or?
|
||||
: SystemColors.Highlight);
|
||||
|
||||
e.Graphics.FillRectangle(sBrush, left + 1, 1, width - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GDIP_DrawBg(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (UseCustomBackground && QueryItemBkColor != null) DoBackGroundCallback(e, visibleColumns);
|
||||
|
||||
if (GridLines)
|
||||
{
|
||||
sPen = new Pen(SystemColors.ControlLight);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
// Columns
|
||||
var iLimit = VisibleRows + 1;
|
||||
for (var i = 1; i < iLimit; i++)
|
||||
{
|
||||
var x = RowsToPixels(i);
|
||||
e.Graphics.DrawLine(sPen, x, 1, x, DrawHeight);
|
||||
}
|
||||
|
||||
// Rows
|
||||
var x1 = RowsToPixels(0) + 1;
|
||||
var jLimit = visibleColumns.Count + 1;
|
||||
for (var j = 0; j < jLimit; j++)
|
||||
{
|
||||
var y = j * CellHeight - _vBar.Value;
|
||||
e.Graphics.DrawLine(sPen, x1, y, DrawWidth, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Columns
|
||||
var y1 = ColumnHeight + 1;
|
||||
var y2 = Height - 1;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var x = column.Left.Value - _hBar.Value;
|
||||
e.Graphics.DrawLine(sPen, x, y1, x, y2);
|
||||
}
|
||||
if (visibleColumns.Count != 0)
|
||||
{
|
||||
var x = TotalColWidth.Value - _hBar.Value;
|
||||
e.Graphics.DrawLine(sPen, x, y1, x, y2);
|
||||
}
|
||||
|
||||
// Rows
|
||||
var x2 = Width + 1;
|
||||
var iLimit = VisibleRows + 1;
|
||||
for (var i = 1; i < iLimit; i++)
|
||||
{
|
||||
var y = RowsToPixels(i);
|
||||
e.Graphics.DrawLine(sPen, 0, y, x2, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedItems.Count != 0) DoSelectionBG(e, visibleColumns);
|
||||
}
|
||||
|
||||
private void GDIP_DrawCellBG(PaintEventArgs e, Color color, Cell cell, IList<RollColumn> visibleColumns)
|
||||
{
|
||||
// We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
int x, y, w;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
x = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
if (x < ColumnWidth) return;
|
||||
y = CellHeight * visibleColumns.IndexOf(cell.Column) + 1 - _vBar.Value;
|
||||
w = CellWidth - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
if (y < ColumnHeight) return;
|
||||
x = cell.Column.Left.Value - _hBar.Value + 1;
|
||||
w = cell.Column.Width.Value - 1;
|
||||
}
|
||||
if (x > DrawWidth || y > DrawHeight) return; // Don't draw if off-screen.
|
||||
|
||||
sBrush = new SolidBrush(color.A == 0 ? Color.FromArgb(255, color) : color);
|
||||
e.Graphics.FillRectangle(sBrush, x, y, w, CellHeight - 1);
|
||||
}
|
||||
|
||||
private void GDIP_DrawString(PaintEventArgs e, string text, Font font, Point point, Color color)
|
||||
{
|
||||
// TextRenderer.DrawText(e.Graphics, text, font, point, color);
|
||||
e.Graphics.DrawString(text, font, new SolidBrush(color), (PointF)point);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -6,380 +6,59 @@ using System.Windows.Forms;
|
|||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// This in the most part now contains renderer selection logic
|
||||
/// </summary>
|
||||
public partial class InputRoll
|
||||
{
|
||||
#region Renderer-Based Logic Methods
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
using (_gdi.LockGraphics(e.Graphics))
|
||||
{
|
||||
_gdi.StartOffScreenBitmap(Width, Height);
|
||||
|
||||
// White Background
|
||||
_gdi.SetBrush(Color.White);
|
||||
_gdi.SetSolidPen(Color.White);
|
||||
_gdi.FillRectangle(0, 0, Width, Height);
|
||||
|
||||
// Lag frame calculations
|
||||
SetLagFramesArray();
|
||||
|
||||
var visibleColumns = _columns.VisibleColumns.ToList();
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
DrawColumnBg(e, visibleColumns);
|
||||
DrawColumnText(e, visibleColumns);
|
||||
}
|
||||
|
||||
// Background
|
||||
DrawBg(e, visibleColumns);
|
||||
|
||||
// Foreground
|
||||
DrawData(e, visibleColumns);
|
||||
|
||||
DrawColumnDrag(e);
|
||||
DrawCellDrag(e);
|
||||
|
||||
_gdi.CopyToScreen();
|
||||
_gdi.EndOffScreenBitmap();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||
{
|
||||
// Do nothing, and this should never be called
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_OnPaint(e);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_OnPaint(e);
|
||||
}
|
||||
|
||||
private void DrawColumnDrag(PaintEventArgs e)
|
||||
{
|
||||
if (_columnDown != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
|
||||
{
|
||||
int x1 = _currentX.Value - (_columnDown.Width.Value / 2);
|
||||
int y1 = _currentY.Value - (CellHeight / 2);
|
||||
int x2 = x1 + _columnDown.Width.Value;
|
||||
int y2 = y1 + CellHeight;
|
||||
|
||||
_gdi.SetSolidPen(_backColor);
|
||||
_gdi.DrawRectangle(x1, y1, x2, y2);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
_gdi.DrawString(_columnDown.Text, new Point(x1 + CellWidthPadding, y1 + CellHeightPadding));
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawColumnDrag(e);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawColumnDrag();
|
||||
}
|
||||
|
||||
private void DrawCellDrag(PaintEventArgs e)
|
||||
{
|
||||
if (_draggingCell != null)
|
||||
{
|
||||
var text = "";
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY);
|
||||
|
||||
Color bgColor = _backColor;
|
||||
QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor);
|
||||
|
||||
int x1 = _currentX.Value - (_draggingCell.Column.Width.Value / 2);
|
||||
int y1 = _currentY.Value - (CellHeight / 2);
|
||||
int x2 = x1 + _draggingCell.Column.Width.Value;
|
||||
int y2 = y1 + CellHeight;
|
||||
|
||||
|
||||
_gdi.SetBrush(bgColor);
|
||||
_gdi.FillRectangle(x1, y1, x2 - x1, y2 - y1);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
_gdi.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawCellDrag(e);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDIP_DrawCellDrag(e);
|
||||
}
|
||||
|
||||
private void DrawColumnText(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int start = -_vBar.Value;
|
||||
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(CellWidthPadding, start + CellHeightPadding);
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
_gdi.DrawString(column.Text, point);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.DrawString(column.Text, point);
|
||||
}
|
||||
|
||||
start += CellHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(column.Left.Value + 2 * CellWidthPadding - _hBar.Value, CellHeightPadding); // TODO: fix this CellPadding issue (2 * CellPadding vs just CellPadding)
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
_gdi.DrawString(column.Text, point);
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.DrawString(column.Text, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawColumnText(e, visibleColumns);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawColumnText(visibleColumns);
|
||||
}
|
||||
|
||||
private void DrawData(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
// Prevent exceptions with small TAStudio windows
|
||||
if (visibleColumns.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (QueryItemText != null)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int startRow = FirstVisibleRow;
|
||||
int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
for (int i = 0, f = 0; f < range; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
int LastVisible = LastVisibleColumnIndex;
|
||||
for (int j = FirstVisibleColumn; j <= LastVisible; j++)
|
||||
{
|
||||
Bitmap image = null;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int bitmapOffsetX = 0;
|
||||
int bitmapOffsetY = 0;
|
||||
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
x = RowsToPixels(i) + CellWidthPadding + bitmapOffsetX;
|
||||
y = (j * CellHeight) + (CellHeightPadding * 2) + bitmapOffsetY;
|
||||
_gdi.DrawBitmap(image, new Point(x, y), true);
|
||||
}
|
||||
|
||||
string text;
|
||||
int strOffsetX = 0;
|
||||
int strOffsetY = 0;
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
// Center Text
|
||||
x = RowsToPixels(i) + ((CellWidth - (text.Length * _charSize.Width)) / 2);
|
||||
y = (j * CellHeight) + CellHeightPadding - _vBar.Value;
|
||||
var point = new Point(x + strOffsetX, y + strOffsetY);
|
||||
|
||||
var rePrep = false;
|
||||
if (j == 1)
|
||||
if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = i + startRow }))
|
||||
{
|
||||
_gdi.PrepDrawString(_rotatedFont, SystemColors.HighlightText);
|
||||
rePrep = true;
|
||||
}
|
||||
else if (j == 1)
|
||||
{
|
||||
// 1. not sure about this; 2. repreps may be excess, but if we render one column at a time, we do need to change back after rendering the header
|
||||
rePrep = true;
|
||||
_gdi.PrepDrawString(_rotatedFont, _foreColor);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
_gdi.DrawString(text, point);
|
||||
}
|
||||
|
||||
if (rePrep)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int startRow = FirstVisibleRow;
|
||||
int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
int xPadding = CellWidthPadding + 1 - _hBar.Value;
|
||||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
int LastVisible = LastVisibleColumnIndex;
|
||||
for (int j = FirstVisibleColumn; j <= LastVisible; j++) // Horizontal
|
||||
{
|
||||
RollColumn col = visibleColumns[j];
|
||||
|
||||
string text;
|
||||
int strOffsetX = 0;
|
||||
int strOffsetY = 0;
|
||||
Point point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding);
|
||||
|
||||
Bitmap image = null;
|
||||
int bitmapOffsetX = 0;
|
||||
int bitmapOffsetY = 0;
|
||||
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
_gdi.DrawBitmap(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding), true);
|
||||
}
|
||||
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
bool rePrep = false;
|
||||
if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow }))
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, SystemColors.HighlightText);
|
||||
rePrep = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
_gdi.DrawString(text, new Point(point.X + strOffsetX, point.Y + strOffsetY));
|
||||
}
|
||||
|
||||
if (rePrep)
|
||||
{
|
||||
_gdi.PrepDrawString(_normalFont, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawData(e, visibleColumns);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawData(visibleColumns);
|
||||
}
|
||||
|
||||
private void DrawColumnBg(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
_gdi.SetBrush(SystemColors.ControlLight);
|
||||
_gdi.SetSolidPen(Color.Black);
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
_gdi.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
|
||||
_gdi.Line(0, 0, 0, visibleColumns.Count * CellHeight + 1);
|
||||
_gdi.Line(ColumnWidth, 0, ColumnWidth, visibleColumns.Count * CellHeight + 1);
|
||||
|
||||
int start = -_vBar.Value;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
_gdi.Line(1, start, ColumnWidth, start);
|
||||
start += CellHeight;
|
||||
}
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
_gdi.Line(1, start, ColumnWidth, start);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int bottomEdge = RowsToPixels(0);
|
||||
|
||||
// Gray column box and black line underneath
|
||||
_gdi.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
|
||||
_gdi.Line(0, 0, TotalColWidth.Value + 1, 0);
|
||||
_gdi.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
|
||||
|
||||
// Vertical black seperators
|
||||
for (int i = 0; i < visibleColumns.Count; i++)
|
||||
{
|
||||
int pos = visibleColumns[i].Left.Value - _hBar.Value;
|
||||
_gdi.Line(pos, 0, pos, bottomEdge);
|
||||
}
|
||||
|
||||
// Draw right most line
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
int right = TotalColWidth.Value - _hBar.Value;
|
||||
_gdi.Line(right, 0, right, bottomEdge);
|
||||
}
|
||||
}
|
||||
|
||||
// Emphasis
|
||||
foreach (var column in visibleColumns.Where(c => c.Emphasis))
|
||||
{
|
||||
_gdi.SetBrush(SystemColors.ActiveBorder);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
_gdi.FillRectangle(1, visibleColumns.IndexOf(column) * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.FillRectangle(column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user is hovering over a column
|
||||
if (IsHoveringOnColumnCell)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (int i = 0; i < visibleColumns.Count; i++)
|
||||
{
|
||||
if (visibleColumns[i] != CurrentCell.Column)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CurrentCell.Column.Emphasis)
|
||||
{
|
||||
_gdi.SetBrush(Add(SystemColors.Highlight, 0x00222222));
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.SetBrush(SystemColors.Highlight);
|
||||
}
|
||||
|
||||
_gdi.FillRectangle(1, i * CellHeight + 1, ColumnWidth - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO multiple selected columns
|
||||
for (int i = 0; i < visibleColumns.Count; i++)
|
||||
{
|
||||
if (visibleColumns[i] == CurrentCell.Column)
|
||||
{
|
||||
// Left of column is to the right of the viewable area or right of column is to the left of the viewable area
|
||||
if (visibleColumns[i].Left.Value - _hBar.Value > Width || visibleColumns[i].Right.Value - _hBar.Value < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int left = visibleColumns[i].Left.Value - _hBar.Value;
|
||||
int width = visibleColumns[i].Right.Value - _hBar.Value - left;
|
||||
|
||||
if (CurrentCell.Column.Emphasis)
|
||||
{
|
||||
_gdi.SetBrush(Add(SystemColors.Highlight, 0x00550000));
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdi.SetBrush(SystemColors.Highlight);
|
||||
}
|
||||
|
||||
_gdi.FillRectangle(left + 1, 1, width - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawColumnBg(e, visibleColumns);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawColumnBg(visibleColumns);
|
||||
}
|
||||
|
||||
// TODO refactor this and DoBackGroundCallback functions.
|
||||
|
@ -388,57 +67,30 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// </summary>
|
||||
private void DrawBg(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (UseCustomBackground && QueryItemBkColor != null)
|
||||
{
|
||||
DoBackGroundCallback(e, visibleColumns);
|
||||
}
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawBg(e, visibleColumns);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawBg(e, visibleColumns);
|
||||
}
|
||||
|
||||
if (GridLines)
|
||||
{
|
||||
_gdi.SetSolidPen(SystemColors.ControlLight);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
// Columns
|
||||
for (int i = 1; i < VisibleRows + 1; i++)
|
||||
{
|
||||
int x = RowsToPixels(i);
|
||||
_gdi.Line(x, 1, x, DrawHeight);
|
||||
}
|
||||
/// <summary>
|
||||
/// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices.
|
||||
/// </summary>
|
||||
private void DrawCellBG(PaintEventArgs e, Color color, Cell cell, List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (Renderer == RollRenderer.GDIPlus)
|
||||
GDIP_DrawCellBG(e, color, cell, visibleColumns);
|
||||
else if (Renderer == RollRenderer.GDI)
|
||||
GDI_DrawCellBG(color, cell, visibleColumns);
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < visibleColumns.Count + 1; i++)
|
||||
{
|
||||
_gdi.Line(RowsToPixels(0) + 1, i * CellHeight - _vBar.Value, DrawWidth, i * CellHeight - _vBar.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Columns
|
||||
int y = ColumnHeight + 1;
|
||||
int? totalColWidth = TotalColWidth;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
int x = column.Left.Value - _hBar.Value;
|
||||
_gdi.Line(x, y, x, Height - 1);
|
||||
}
|
||||
#endregion
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
_gdi.Line(totalColWidth.Value - _hBar.Value, y, totalColWidth.Value - _hBar.Value, Height - 1);
|
||||
}
|
||||
#region Non-Renderer-Specific Methods
|
||||
|
||||
// Rows
|
||||
for (int i = 1; i < VisibleRows + 1; i++)
|
||||
{
|
||||
_gdi.Line(0, RowsToPixels(i), Width + 1, RowsToPixels(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedItems.Any())
|
||||
{
|
||||
DoSelectionBG(e, visibleColumns);
|
||||
}
|
||||
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||
{
|
||||
// Do nothing, and this should never be called
|
||||
}
|
||||
|
||||
private void DoSelectionBG(PaintEventArgs e, List<RollColumn> visibleColumns)
|
||||
|
@ -484,49 +136,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
cellColor = Color.FromArgb(cellColor.R - (int)((cellColor.R - SystemColors.Highlight.R) * alpha),
|
||||
cellColor.G - (int)((cellColor.G - SystemColors.Highlight.G) * alpha),
|
||||
cellColor.B - (int)((cellColor.B - SystemColors.Highlight.B) * alpha));
|
||||
DrawCellBG(cellColor, relativeCell, visibleColumns);
|
||||
DrawCellBG(e, cellColor, relativeCell, visibleColumns);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a cell with rowindex inbetween 0 and VisibleRows, it draws the background color specified. Do not call with absolute rowindices.
|
||||
/// </summary>
|
||||
private void DrawCellBG(Color color, Cell cell, List<RollColumn> visibleColumns)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
x = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
w = CellWidth - 1;
|
||||
y = (CellHeight * visibleColumns.IndexOf(cell.Column)) + 1 - _vBar.Value; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
h = CellHeight - 1;
|
||||
if (x < ColumnWidth)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w = cell.Column.Width.Value - 1;
|
||||
x = cell.Column.Left.Value - _hBar.Value + 1;
|
||||
y = RowsToPixels(cell.RowIndex.Value) + 1; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
h = CellHeight - 1;
|
||||
if (y < ColumnHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (x > DrawWidth || y > DrawHeight)
|
||||
{
|
||||
return;
|
||||
} // Don't draw if off screen.
|
||||
|
||||
_gdi.SetBrush(color);
|
||||
_gdi.FillRectangle(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls QueryItemBkColor callback for all visible cells and fills in the background of those cells.
|
||||
/// </summary>
|
||||
|
@ -546,7 +159,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
for (int i = 0, f = 0; f < range; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
|
||||
|
||||
Color rowColor = Color.White;
|
||||
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
|
||||
|
||||
|
@ -573,7 +186,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
Column = visibleColumns[j],
|
||||
RowIndex = i
|
||||
};
|
||||
DrawCellBG(itemColor, cell, visibleColumns);
|
||||
DrawCellBG(e, itemColor, cell, visibleColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -583,7 +196,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
|
||||
|
||||
Color rowColor = Color.White;
|
||||
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
|
||||
|
||||
|
@ -610,11 +223,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
Column = visibleColumns[j],
|
||||
RowIndex = i
|
||||
};
|
||||
DrawCellBG(itemColor, cell, visibleColumns);
|
||||
DrawCellBG(e, itemColor, cell, visibleColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Row width is specified for horizontal orientation
|
||||
public partial class InputRoll : Control
|
||||
{
|
||||
private readonly GDIRenderer _gdi;
|
||||
private RollRenderer Renderer = RollRenderer.GDIPlus;
|
||||
|
||||
private Font _commonFont;
|
||||
|
||||
private readonly SortedSet<Cell> _selectedItems = new SortedSet<Cell>(new SortCell());
|
||||
|
||||
private readonly VScrollBar _vBar;
|
||||
|
@ -24,8 +27,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
private readonly Timer _hoverTimer = new Timer();
|
||||
private readonly byte[] _lagFrames = new byte[256]; // Large enough value that it shouldn't ever need resizing. // apparently not large enough for 4K
|
||||
|
||||
private readonly IntPtr _rotatedFont;
|
||||
private readonly IntPtr _normalFont;
|
||||
private readonly Color _foreColor;
|
||||
private readonly Color _backColor;
|
||||
|
||||
|
@ -35,7 +36,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
private int _maxCharactersInHorizontal = 1;
|
||||
|
||||
private int _rowCount;
|
||||
private Size _charSize;
|
||||
|
||||
private RollColumn _columnDown;
|
||||
|
||||
|
@ -52,6 +52,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public InputRoll()
|
||||
{
|
||||
// set renderer once at InputRoll instantiation
|
||||
Renderer = (RollRenderer)TAStudio.InputRollRenderer;
|
||||
|
||||
UseCustomBackground = true;
|
||||
GridLines = true;
|
||||
CellWidthPadding = 3;
|
||||
|
@ -59,24 +62,29 @@ namespace BizHawk.Client.EmuHawk
|
|||
CurrentCell = null;
|
||||
ScrollMethod = "near";
|
||||
|
||||
var commonFont = new Font("Arial", 8, FontStyle.Bold);
|
||||
_normalFont = GDIRenderer.CreateNormalHFont(commonFont, 6);
|
||||
|
||||
// PrepDrawString doesn't actually set the font, so this is rather useless.
|
||||
// I'm leaving this stuff as-is so it will be a bit easier to fix up with another rendering method.
|
||||
_rotatedFont = GDIRenderer.CreateRotatedHFont(commonFont, true);
|
||||
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
SetStyle(ControlStyles.Opaque, true);
|
||||
|
||||
_gdi = new GDIRenderer();
|
||||
|
||||
using (var g = CreateGraphics())
|
||||
using (_gdi.LockGraphics(g))
|
||||
switch (Renderer)
|
||||
{
|
||||
_charSize = _gdi.MeasureString("A", commonFont); // TODO make this a property so changing it updates other values.
|
||||
case RollRenderer.GDI:
|
||||
_commonFont = new Font("Arial", 8, FontStyle.Bold);
|
||||
_normalFont = GDIRenderer.CreateNormalHFont(_commonFont, 6);
|
||||
|
||||
// PrepDrawString doesn't actually set the font, so this is rather useless.
|
||||
// I'm leaving this stuff as-is so it will be a bit easier to fix up with another rendering method.
|
||||
_rotatedFont = GDIRenderer.CreateRotatedHFont(_commonFont, true);
|
||||
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
SetStyle(ControlStyles.Opaque, true);
|
||||
|
||||
_gdi = new GDIRenderer();
|
||||
GDIConstruction();
|
||||
break;
|
||||
case RollRenderer.GDIPlus:
|
||||
// _commonFont = new Font("Courier New", 8, FontStyle.Bold);
|
||||
_commonFont = new Font("Arial", 8, FontStyle.Bold);
|
||||
GDIPConstruction();
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateCellSize();
|
||||
|
@ -126,11 +134,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_gdi.Dispose();
|
||||
|
||||
GDIRenderer.DestroyHFont(_normalFont);
|
||||
GDIRenderer.DestroyHFont(_rotatedFont);
|
||||
|
||||
if (Renderer == RollRenderer.GDI) GDIDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
@ -193,7 +197,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
return _hBar.SmallChange / CellWidth;
|
||||
}
|
||||
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
return _vBar.SmallChange / CellHeight;
|
||||
}
|
||||
|
||||
|
@ -643,7 +647,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
return _hBar.Value / CellWidth;
|
||||
}
|
||||
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
return _vBar.Value / CellHeight;
|
||||
}
|
||||
|
||||
|
@ -771,6 +775,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
get
|
||||
{
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
return (DrawWidth - ColumnWidth) / CellWidth;
|
||||
|
@ -789,6 +794,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
get
|
||||
{
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
return _vBar.Value / CellHeight;
|
||||
|
@ -805,6 +811,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
get
|
||||
{
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
List<RollColumn> columnList = VisibleColumns.ToList();
|
||||
int ret;
|
||||
if (HorizontalOrientation)
|
||||
|
@ -1009,7 +1016,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
Refresh();
|
||||
}
|
||||
}
|
||||
else if (_columnDown != null) // Kind of silly feeling to have this check twice, but the only alternative I can think of has it refreshing twice when pointed column changes with column down, and speed matters
|
||||
else if (_columnDown != null) // Kind of silly feeling to have this check twice, but the only alternative I can think of has it refreshing twice when pointed column changes with column down, and speed matters
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
@ -1579,10 +1586,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
// See MSDN Page for more information on the dumb ScrollBar.Maximum Property
|
||||
private void RecalculateScrollBars()
|
||||
{
|
||||
if (_vBar == null || _hBar == null) return;
|
||||
|
||||
UpdateDrawSize();
|
||||
|
||||
var columns = _columns.VisibleColumns.ToList();
|
||||
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
NeedsVScrollbar = columns.Count > DrawHeight / CellHeight;
|
||||
|
@ -1763,6 +1773,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
newCell.RowIndex = PixelsToRows(x);
|
||||
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
|
||||
int colIndex = (y + _vBar.Value) / CellHeight;
|
||||
if (colIndex >= 0 && colIndex < columns.Count)
|
||||
{
|
||||
|
@ -1798,7 +1810,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// <returns>The new width of the RollColumn object.</returns>
|
||||
private int UpdateWidth(RollColumn col)
|
||||
{
|
||||
col.Width = (col.Text.Length * _charSize.Width) + (CellWidthPadding * 4);
|
||||
switch (Renderer)
|
||||
{
|
||||
case RollRenderer.GDI:
|
||||
col.Width = (col.Text.Length * _charSize.Width) + (CellWidthPadding * 4);
|
||||
break;
|
||||
case RollRenderer.GDIPlus:
|
||||
col.Width = (int)Math.Round((col.Text.Length * _charSizeF.Width) + (CellWidthPadding * 4));
|
||||
break;
|
||||
}
|
||||
return col.Width.Value;
|
||||
}
|
||||
|
||||
|
@ -1863,6 +1883,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
return (int)Math.Floor((float)(pixels - ColumnWidth) / CellWidth);
|
||||
}
|
||||
if (CellHeight == 0) CellHeight++;
|
||||
return (int)Math.Floor((float)(pixels - ColumnHeight) / CellHeight);
|
||||
}
|
||||
|
||||
|
@ -1889,8 +1910,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// </summary>
|
||||
private void UpdateCellSize()
|
||||
{
|
||||
CellHeight = _charSize.Height + (CellHeightPadding * 2);
|
||||
CellWidth = (_charSize.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4); // Double the padding for horizontal because it looks better
|
||||
switch (Renderer)
|
||||
{
|
||||
case RollRenderer.GDI:
|
||||
CellHeight = _charSize.Height + (CellHeightPadding * 2);
|
||||
CellWidth = (_charSize.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4); // Double the padding for horizontal because it looks better
|
||||
break;
|
||||
case RollRenderer.GDIPlus:
|
||||
CellHeight = (int)Math.Round(_charSizeF.Height + (CellHeightPadding * 2) + 1); // needed for GDI+ to match GDI cell height
|
||||
CellWidth = (int)Math.Round((_charSizeF.Width * MaxCharactersInHorizontal) + (CellWidthPadding * 4)); // Double the padding for horizontal because it looks better
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// SuuperW: Count lag frames between FirstDisplayed and given display position
|
||||
|
@ -2260,6 +2290,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
public enum RollRenderer
|
||||
{
|
||||
GDI = 0,
|
||||
GDIPlus = 1
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,6 +125,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.DefaultStateSettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SettingsSubMenu = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.RotateMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.RendererOptionsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SetRenderer0 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SetRenderer1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HideLagFramesSubMenu = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HideLagFrames0 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HideLagFrames1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -964,6 +967,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
//
|
||||
this.SettingsSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.RotateMenuItem,
|
||||
this.RendererOptionsMenuItem,
|
||||
this.HideLagFramesSubMenu,
|
||||
this.iconsToolStripMenuItem,
|
||||
this.toolStripSeparator23,
|
||||
|
@ -982,6 +986,34 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.RotateMenuItem.Text = "Rotate";
|
||||
this.RotateMenuItem.Click += new System.EventHandler(this.RotateMenuItem_Click);
|
||||
//
|
||||
// RendererOptionsMenuItem
|
||||
//
|
||||
this.RendererOptionsMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SetRenderer0,
|
||||
this.SetRenderer1});
|
||||
this.RendererOptionsMenuItem.Name = "RendererOptionsMenuItem";
|
||||
this.RendererOptionsMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.RendererOptionsMenuItem.Text = "Renderer";
|
||||
this.RendererOptionsMenuItem.DropDownOpened += new System.EventHandler(this.SelectedRendererSubMenu_DropDownOpened);
|
||||
//
|
||||
// SetRenderer0
|
||||
//
|
||||
this.SetRenderer0.CheckOnClick = true;
|
||||
this.SetRenderer0.Name = "SetRenderer0";
|
||||
this.SetRenderer0.Size = new System.Drawing.Size(180, 22);
|
||||
this.SetRenderer0.Tag = 0;
|
||||
this.SetRenderer0.Text = "GDI";
|
||||
this.SetRenderer0.Click += new System.EventHandler(this.SetRenderer_Click);
|
||||
//
|
||||
// SetRenderer1
|
||||
//
|
||||
this.SetRenderer1.CheckOnClick = true;
|
||||
this.SetRenderer1.Name = "SetRenderer1";
|
||||
this.SetRenderer1.Size = new System.Drawing.Size(180, 22);
|
||||
this.SetRenderer1.Tag = 1;
|
||||
this.SetRenderer1.Text = "GDI+ (Experimental)";
|
||||
this.SetRenderer1.Click += new System.EventHandler(this.SetRenderer_Click);
|
||||
//
|
||||
// HideLagFramesSubMenu
|
||||
//
|
||||
this.HideLagFramesSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
|
@ -1816,5 +1848,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
private System.Windows.Forms.ToolStripMenuItem AutoRestoreOnMouseUpOnlyMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SingleClickFloatEditMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem LoadBranchOnDoubleclickMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem RendererOptionsMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SetRenderer0;
|
||||
private System.Windows.Forms.ToolStripMenuItem SetRenderer1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using BizHawk.Client.Common;
|
|||
using BizHawk.Client.Common.MovieConversionExtensions;
|
||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -1115,6 +1116,51 @@ namespace BizHawk.Client.EmuHawk
|
|||
RotateMenuItem.ShortcutKeyDisplayString = TasView.RotateHotkeyStr;
|
||||
}
|
||||
|
||||
private void SelectedRendererSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows)
|
||||
{
|
||||
if (Global.Config.TasStudioRenderer != InputRollRenderer)
|
||||
{
|
||||
switch (Global.Config.TasStudioRenderer)
|
||||
{
|
||||
case 0:
|
||||
SetRenderer0.Text = "GDI (Pending TAStudio Restart)";
|
||||
SetRenderer0.Enabled = false;
|
||||
SetRenderer0.Checked = true;
|
||||
SetRenderer1.Text = "GDI+ (Experimental)";
|
||||
SetRenderer1.Checked = false;
|
||||
break;
|
||||
case 1:
|
||||
SetRenderer1.Text = "GDI+ (Pending TAStudio Restart)";
|
||||
SetRenderer1.Enabled = false;
|
||||
SetRenderer1.Checked = true;
|
||||
SetRenderer0.Text = "GDI";
|
||||
SetRenderer0.Checked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderer0.Text = "GDI";
|
||||
SetRenderer0.Enabled = true;
|
||||
SetRenderer1.Text = "GDI+ (Experimental)";
|
||||
SetRenderer1.Enabled = true;
|
||||
SetRenderer0.Checked = Global.Config.TasStudioRenderer == 0;
|
||||
SetRenderer1.Checked = Global.Config.TasStudioRenderer == 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderer0.Checked = false;
|
||||
SetRenderer0.Enabled = false;
|
||||
SetRenderer0.Visible = false;
|
||||
SetRenderer1.Checked = true;
|
||||
SetRenderer1.Enabled = false;
|
||||
SetRenderer1.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void HideLagFramesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
HideLagFrames0.Checked = TasView.LagFramesToHide == 0;
|
||||
|
@ -1163,6 +1209,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
CurrentTasMovie.FlagChanges();
|
||||
}
|
||||
|
||||
private void SetRenderer_Click(object sender, EventArgs e)
|
||||
{
|
||||
var incoming = (int)(sender as ToolStripMenuItem).Tag;
|
||||
if (incoming != InputRollRenderer)
|
||||
{
|
||||
MessageBox.Show("Changing the input roll renderer requires a\nmanual restart of TAStudio", "Renderer Change Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
Global.Config.TasStudioRenderer = incoming;
|
||||
}
|
||||
|
||||
private void HideLagFramesX_Click(object sender, EventArgs e)
|
||||
{
|
||||
TasView.LagFramesToHide = (int)((ToolStripMenuItem)sender).Tag;
|
||||
|
|
|
@ -15,6 +15,7 @@ using BizHawk.Client.Common.MovieConversionExtensions;
|
|||
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -25,6 +26,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
public TasMovie CurrentTasMovie => Global.MovieSession.Movie as TasMovie;
|
||||
private MainForm Mainform => GlobalWin.MainForm;
|
||||
|
||||
/// <summary>
|
||||
/// Static settings so that InputRoll.cs can determine its renderer ahead of instantiation
|
||||
/// 0: GDI
|
||||
/// 1: GDI+
|
||||
/// </summary>
|
||||
public static int InputRollRenderer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? 0 : 1;
|
||||
|
||||
public bool IsInMenuLoop { get; private set; }
|
||||
public string StatesPath => PathManager.MakeAbsolutePath(Global.Config.PathEntries["Global", "TAStudio states"].Path, null);
|
||||
|
||||
|
@ -113,6 +121,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
public TAStudio()
|
||||
{
|
||||
Settings = new TAStudioSettings();
|
||||
|
||||
// input roll renderer must be set before InputRoll initialisation
|
||||
InputRollRenderer = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows ? Global.Config.TasStudioRenderer : 1;
|
||||
|
||||
InitializeComponent();
|
||||
InitializeSeekWorker();
|
||||
|
||||
|
|
|
@ -123,19 +123,19 @@
|
|||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="RecentSubMenu.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALAQAA
|
||||
CwEBNnBPWwAAAk1JREFUOE+VkktvUlEUhVsfsdHoREcOHJr4C/RPONHoXzBxoOlAJybOlAZtkdSa2piY
|
||||
NsjjFiiX8qY8ChYL+ECB2lKB8rq0k5bEmiiRbtc+6b2B6MTBR/ZZa+919j3tEBH9RbudHD6E63/2qAwc
|
||||
treT58BVRVnWl8vBbLEg7wNC/QPaMrwb4GT/jFa024mzQLe56c9GwjM7klXXlcw6ksyPSbLoKByc/lUq
|
||||
+TbQMwrODARAGAF3SxtexSMbf8vOCVp9ZyK+/euaW9TO+SfksOlprSjvoteAjU5rAYqSuFyvR1PR8Ewv
|
||||
GJii8rcAoYFSb+d4gDAgNI/8jGTHOFUroT3410QAHuk4Am4Vi/KOzz2JGxfFcLMZI3wK5T7ZqaXEhcYb
|
||||
WU2PKJM2H7Ra8XE14AQO91dTpk4k9JLq9YgYHghoxcWZPa/bSCH/C2o0orPaBo1GbDQee9VJxF+zoYFP
|
||||
wtpGWgpN0/uMRWgcyiG1WsSkBhxFwG0E7AV8z2lrKyxuYvgBs2kLr4z1XcLj4SA2gD+nBhxB8p1sxtKZ
|
||||
t4xR/otTDNdqS1oQw7ezx2/AfxVok1oAmh+WSt7v/MKLLgOtr3tEQD+sseeyPyX0dqHdVAOGq9XQPazX
|
||||
/JyzH9itY+SQ9LSSnKV8fkHANWvsoYc/JYaZERHAPzicBw9AoZBf+BnwTZEN/4G2N4egZg1eDz05cIHn
|
||||
tACmUgmeAtdhRsvlwH6x6Dr4+EESoO5B68JLo+eSOjMQwKDpGLgCJtDoBysgBXzQDOBifz8zcPh/aOgP
|
||||
7nYTiVA2JaoAAAAASUVORK5CYII=
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
|
||||
JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsBAAALAQE2cE9bAAACTUlE
|
||||
QVQ4T5WSS29SURSFWx+x0ehERw4cmvgL9E840ehfMHGg6UAnJs6UBm2R1JramJg2yOMWKJfypjwKFgv4
|
||||
QIHaUoHyurSTlsSaKJFu1z7pvYHoxMFH9llr73X2Pe0QEf1Fu50cPoTrf/aoDBy2t5PnwFVFWdaXy8Fs
|
||||
sSDvA0L9A9oyvBvgZP+MVrTbibNAt7npz0bCMzuSVdeVzDqSzI9JsugoHJz+VSr5NtAzCs4MBEAYAXdL
|
||||
G17FIxt/y84JWn1nIr7965pb1M75J+Sw6WmtKO+i14CNTmsBipK4XK9HU9HwTC8YmKLytwChgVJv53iA
|
||||
MCA0j/yMZMc4VSuhPfjXRAAe6TgCbhWL8o7PPYkbF8VwsxkjfArlPtmppcSFxhtZTY8okzYftFrxcTXg
|
||||
BA73V1OmTiT0kur1iBgeCGjFxZk9r9tIIf8LajSis9oGjUZsNB571UnEX7OhgU/C2kZaCk3T+4xFaBzK
|
||||
IbVaxKQGHEXAbQTsBXzPaWsrLG5i+AGzaQuvjPVdwuPhIDaAP6cGHEHynWzG0pm3jFH+i1MM12pLWhDD
|
||||
t7PHb8B/FWiTWgCaH5ZK3u/8wosuA62ve0RAP6yx57I/JfR2od1UA4ar1dA9rNf8nLMf2K1j5JD0tJKc
|
||||
pXx+QcA1a+yhhz8lhpkREcA/OJwHD0ChkF/4GfBNkQ3/gbY3h6BmDV4PPTlwgee0AKZSCZ4C12FGy+XA
|
||||
frHoOvj4QRKg7kHrwkuj55I6MxDAoOkYuAIm0OgHKyAFfNAM4GJ/PzNw+H9o6A/udhOJUDYlqgAAAABJ
|
||||
RU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="TasStatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
|
|
Loading…
Reference in New Issue