diff --git a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
index d74861b92df..887e2c1dd37 100644
--- a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
+++ b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.History.cs
@@ -60,7 +60,10 @@ public interface IMovieChangeLog
///
/// Undoes the most recent action batch, if any exist.
///
- void Undo();
+ /// If given, as many actions will be undone as needed to make the action
+ /// of the given ID the most recent action. The action with the given ID will not be undone.
+ ///
+ void Undo(int? untilId = null);
///
/// Redoes the most recent undo, if any exist.
@@ -248,13 +251,26 @@ public bool MergeActions(int action1, int action2)
return true;
}
- public void Undo()
+ public void Undo(int? untilId = null)
{
if (UndoIndex == -1)
{
return;
}
+ if (untilId != null)
+ {
+ int id = untilId.Value;
+ _movie.SingleInvalidation(() =>
+ {
+ while (UndoIndex >= 0 && id < _history[UndoIndex].id)
+ {
+ Undo();
+ }
+ });
+ return;
+ }
+
List batch = _history[UndoIndex].actions;
UndoIndex--;
diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/Cell.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/Cell.cs
index f52b07f6133..b3c1114f12c 100644
--- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/Cell.cs
+++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/Cell.cs
@@ -1,7 +1,6 @@
#nullable enable
using System.Collections.Generic;
-using System.Diagnostics;
using BizHawk.Common;
using BizHawk.Common.CollectionExtensions;
@@ -106,7 +105,8 @@ public override void Add(Cell item)
var i = _list.BinarySearch(item);
if (i >= 0)
{
- Debug.Assert(false, $"{nameof(CellList)}'s distinctness invariant was almost broken! CellList.Add({(item is null ? "null" : item.ToString())})");
+ // We can end up adding cells that are already selected pretty easily, by combining Alt multi-selection with Shift range-selection.
+ // System.Diagnostics.Debug.Assert(false, $"{nameof(CellList)}'s distinctness invariant was almost broken! CellList.Add({(item is null ? "null" : item.ToString())})");
return;
}
_list.Insert(~i, item);
diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs
index 0034e9519c3..2a39bf073f1 100644
--- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs
+++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs
@@ -425,6 +425,12 @@ public int HoverInterval
[Category("Virtual")]
public event QueryFrameLagHandler QueryFrameLag;
+ ///
+ /// Fires when a cell that can be selected is clicked. Return null to use default selection logic.
+ ///
+ [Category("Mouse")]
+ public event QueryShouldSelectCellHandler QueryShouldSelectCell;
+
///
/// Fires when the mouse moves from one cell to another (including column header cells)
///
@@ -502,6 +508,11 @@ public int HoverInterval
///
public delegate bool QueryFrameLagHandler(int index, bool hideWasLag);
+ ///
+ /// Check if clicking the current cell should select it.
+ ///
+ public delegate bool? QueryShouldSelectCellHandler(MouseButtons button);
+
public delegate void CellChangeEventHandler(object sender, CellEventArgs e);
public delegate void HoverEventHandler(object sender, CellEventArgs e);
@@ -1115,7 +1126,6 @@ protected override void OnMouseLeave(EventArgs e)
base.OnMouseLeave(e);
}
- // TODO add query callback of whether to select the cell or not
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
@@ -1140,17 +1150,37 @@ protected override void OnMouseDown(MouseEventArgs e)
{
RightButtonHeld = true;
}
+
+ // In the case that we have a context menu already open, we must manually update the CurrentCell as MouseMove isn't triggered while it is open.
+ if (AllowRightClickSelection && CurrentCell == null)
+ OnMouseMove(e);
+ }
+
+ bool shouldSelect = false;
+ bool useDefaultSelection = true;
+ if (IsHoveringOnDataCell)
+ {
+ if (QueryShouldSelectCell != null)
+ {
+ bool? result = QueryShouldSelectCell(e.Button);
+ shouldSelect = result != false;
+ useDefaultSelection = result == null;
+ }
+ else
+ {
+ shouldSelect = true;
+ }
}
if (e.Button == MouseButtons.Left)
{
- if (IsHoveringOnDataCell)
+ if (shouldSelect)
{
if (ModifierKeys == Keys.Alt)
{
// do marker drag here
}
- else if (ModifierKeys is Keys.Shift && CurrentCell.Column! is { Type: ColumnType.Text } col)
+ else if (ModifierKeys is Keys.Shift && (!useDefaultSelection || CurrentCell.Column!.Type is ColumnType.Text))
{
if (_selectedItems.Count is not 0)
{
@@ -1182,7 +1212,7 @@ protected override void OnMouseDown(MouseEventArgs e)
additionEndExcl = targetRow + 1;
}
}
- for (var i = additionStart; i < additionEndExcl; i++) SelectCell(new() { RowIndex = i, Column = col });
+ for (var i = additionStart; i < additionEndExcl; i++) SelectCell(new() { RowIndex = i, Column = CurrentCell.Column });
}
}
else
@@ -1195,7 +1225,7 @@ protected override void OnMouseDown(MouseEventArgs e)
SelectCell(CurrentCell);
}
}
- else if (ModifierKeys is Keys.Control && CurrentCell.Column!.Type is ColumnType.Text)
+ else if (ModifierKeys is Keys.Control && (!useDefaultSelection || CurrentCell.Column!.Type is ColumnType.Text))
{
SelectCell(CurrentCell, toggle: true);
}
@@ -1213,11 +1243,7 @@ protected override void OnMouseDown(MouseEventArgs e)
if (AllowRightClickSelection && e.Button == MouseButtons.Right)
{
- // In the case that we have a context menu already open, we must manually update the CurrentCell as MouseMove isn't triggered while it is open.
- if (CurrentCell == null)
- OnMouseMove(e);
-
- if (!IsHoveringOnColumnCell)
+ if (shouldSelect)
{
// If this cell is not currently selected, clear and select
if (!_selectedItems.Contains(CurrentCell))
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs
index b3d1f55c246..2d2fd19072d 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs
@@ -1,8 +1,10 @@
+using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Globalization;
+
using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Client.Common;
@@ -18,7 +20,6 @@ public partial class TAStudio
private string _startAxisDrawColumn = "";
private bool _boolPaintState;
private int _axisPaintState;
- private int _axisBackupState;
private bool _patternPaint;
private bool _startCursorDrag;
private bool _startSelectionDrag;
@@ -29,22 +30,59 @@ public partial class TAStudio
private bool _batchEditing;
// Editing analog input
- private string _axisEditColumn = "";
- private int _axisEditRow = -1;
- private string _axisTypedValue;
- private int _axisEditYPos = -1;
- private int AxisEditRow
+ private string/*?*/ __axisEditColumn = null; // __ do not access directly
+ private string/*?*/ AxisEditColumn
{
+ get => __axisEditColumn;
set
{
- _axisEditRow = value;
- TasView.SuspendHotkeys = AxisEditingMode;
+ // If we're changing column, exit axis editing mode first.
+ if (AxisEditingMode && value != null) __axisEditColumn = null;
+
+ __axisEditColumn = value;
+ _axisEditYPos = -1;
+
+ if (AxisEditingMode)
+ {
+ _axisTypedValue = "";
+ _didAxisType = false;
+ _axisRestoreId = CurrentTasMovie.ChangeLog.MostRecentId;
+ TasView.SuspendHotkeys = true;
+ }
+ else
+ {
+ if (_didAxisType)
+ {
+ _didAxisType = false;
+ CurrentTasMovie.ChangeLog.EndBatch();
+ }
+ TasView.SuspendHotkeys = false;
+ }
}
}
- public bool AxisEditingMode => _axisEditRow != -1;
+ private string _axisTypedValue = "";
+ private bool _didAxisType;
+ private int _axisEditYPos = -1;
+ private int _axisRestoreId;
+
+ ///
+ /// Begin editing an axis value by dragging the mouse.
+ ///
+ /// The initial vertical position of the cursor.
+ private void BeginAxisMouseEdit(int yPos)
+ {
+ Debug.Assert(AxisEditingMode, "Don't begin axis mouse edit outside of axis editing mode.");
+
+ _axisEditYPos = yPos;
+ _axisTypedValue = "";
+ _didAxisType = false;
+ _axisRestoreId = CurrentTasMovie.ChangeLog.MostRecentId;
+
+ CurrentTasMovie.ChangeLog.BeginNewBatch($"Axis mouse edit, frame {TasView.SelectedRows.First()}");
+ }
- private readonly List _extraAxisRows = new List();
+ public bool AxisEditingMode => AxisEditColumn != null;
// Right-click dragging
private string[] _rightClickInput;
@@ -189,9 +227,7 @@ private void TasView_QueryItemBkColor(int index, RollColumn column, ref Color co
color = Color.FromArgb(0x60, 0xFF, 0xFF, 0xFF);
}
}
- else if (AxisEditingMode
- && (index == _axisEditRow || _extraAxisRows.Contains(index))
- && columnName == _axisEditColumn)
+ else if (columnName == AxisEditColumn && TasView.IsRowSelected(index))
{
color = Palette.AnalogEdit_Col;
}
@@ -250,6 +286,31 @@ private void TasView_QueryRowBkColor(int index, ref Color color)
}
}
+ private bool? TasView_QueryShouldSelect(MouseButtons button)
+ {
+ if (AxisEditingMode)
+ {
+ if (ModifierKeys == Keys.Shift || ModifierKeys == Keys.Control)
+ {
+ // This just makes it easier to select multiple rows with axis editing mode, by allowing multiple row selection when clicking columns that aren't the frame column.
+ return true;
+ }
+ else if (TasView.CurrentCell.Column.Name == AxisEditColumn && TasView.IsRowSelected(TasView.CurrentCell.RowIndex.Value))
+ {
+ // We will start editing via mouse, so don't unselect if we have multiple selected rows.
+ return false;
+ }
+ else
+ {
+ // Exit axis editing mode (ideally we wouldn't change state in the query method, but we can't do this on mouse down because the selection will have already changed)
+ AxisEditColumn = null;
+ SetTasViewRowCount();
+ }
+ }
+
+ return null;
+ }
+
private readonly string[] _formatCache = Enumerable.Range(1, 10).Select(i => $"D{i}").ToArray();
/// with leading zeroes such that every frame in the movie will be printed with the same number of digits
@@ -294,12 +355,10 @@ private void TasView_QueryItemText(int index, RollColumn column, out string text
else if (column.Type is ColumnType.Boolean or ColumnType.Axis)
{
// Display typed float value (string "-" can't be parsed, so CurrentTasMovie.DisplayValue can't return it)
- if ((index == _axisEditRow || _extraAxisRows.Contains(index))
- && columnName == _axisEditColumn)
+ bool axisEditing = columnName == AxisEditColumn && TasView.IsRowSelected(index);
+ if (axisEditing && _didAxisType)
{
- text = _axisTypedValue.Length == 0
- ? _axisBackupState.ToString()
- : _axisTypedValue;
+ text = _axisTypedValue;
}
else if (index < CurrentTasMovie.InputLogLength)
{
@@ -307,7 +366,7 @@ private void TasView_QueryItemText(int index, RollColumn column, out string text
if (column.Type == ColumnType.Axis)
{
// feos: this could be cached, but I don't notice any slowdown this way either
- if (text == ((float) ControllerType.Axes[columnName].Neutral).ToString(NumberFormatInfo.InvariantInfo))
+ if (!axisEditing && text == ((float) ControllerType.Axes[columnName].Neutral).ToString(NumberFormatInfo.InvariantInfo))
{
text = "";
}
@@ -512,39 +571,17 @@ private void TasView_MouseDown(object sender, MouseEventArgs e)
{
_leftButtonHeld = true;
- // SuuperW: Exit axis editing mode, or re-enter mouse editing
if (AxisEditingMode)
{
if (ModifierKeys is Keys.Control or Keys.Shift)
{
- _extraAxisRows.Clear();
- _extraAxisRows.AddRange(TasView.SelectedRows);
- _startSelectionDrag = true;
- _selectionDragState = TasView.IsRowSelected(frame);
- return;
- }
-
- if (_axisEditColumn != buttonName
- || !(_axisEditRow == frame || _extraAxisRows.Contains(frame)))
- {
- _extraAxisRows.Clear();
- AxisEditRow = -1;
- SetTasViewRowCount();
+ // User was selecting additional rows.
}
else
{
- if (_extraAxisRows.Contains(frame))
- {
- _extraAxisRows.Clear();
- AxisEditRow = frame;
- SetTasViewRowCount();
- }
-
- _axisEditYPos = e.Y;
- _axisPaintState = CurrentTasMovie.GetAxisState(frame, buttonName);
-
- return;
+ BeginAxisMouseEdit(e.Y);
}
+ return;
}
if (targetCol.Name is CursorColumnName)
@@ -652,18 +689,14 @@ private void TasView_MouseDown(object sender, MouseEventArgs e)
}
else // Double-click enters axis editing mode
{
- if (_axisEditColumn == buttonName && _axisEditRow == frame)
+ if (AxisEditColumn != null && (AxisEditColumn != buttonName || !TasView.IsRowSelected(frame)))
{
- AxisEditRow = -1;
+ AxisEditColumn = null;
}
else
{
- CurrentTasMovie.ChangeLog.BeginNewBatch($"Axis Edit: {frame}");
- _axisEditColumn = buttonName;
- AxisEditRow = frame;
- _axisTypedValue = "";
- _axisEditYPos = e.Y;
- _axisBackupState = CurrentTasMovie.GetAxisState(_axisEditRow, _axisEditColumn);
+ AxisEditColumn = buttonName;
+ BeginAxisMouseEdit(e.Y);
}
RefreshDialog();
@@ -731,14 +764,6 @@ private void TasView_MouseDown(object sender, MouseEventArgs e)
}
}
- ///
- /// Begins a batch of edits, for auto-restore purposes. Auto-restore will be delayed until EndBatchEdit is called.
- ///
- private void BeginBatchEdit()
- {
- _batchEditing = true;
- }
-
/// Returns true if the input list was redrawn.
private bool EndBatchEdit()
{
@@ -874,20 +899,13 @@ private void ClearLeftMouseStates()
_startAxisDrawColumn = "";
TasView.ReleaseCurrentCell();
- // Exit axis editing if value was changed with cursor
- if (AxisEditingMode && _axisPaintState != CurrentTasMovie.GetAxisState(_axisEditRow, _axisEditColumn))
- {
- AxisEditRow = -1;
- }
- _axisPaintState = 0;
- _axisEditYPos = -1;
+ CurrentTasMovie.ChangeLog.EndBatch();
- if (!AxisEditingMode)
- {
- CurrentTasMovie.ChangeLog?.EndBatch();
- }
+ _axisEditYPos = -1; // exit mouse edit mode
MainForm.BlockFrameAdvance = false;
+
+ RefreshDialog(); // Even if no edits happened, the undo form may need updating because we potentially ended a batch.
}
private void TasView_MouseUp(object sender, MouseEventArgs e)
@@ -925,15 +943,7 @@ private void TasView_MouseUp(object sender, MouseEventArgs e)
}
else if (e.Button == MouseButtons.Left)
{
- if (AxisEditingMode && ModifierKeys is Keys.Control or Keys.Shift)
- {
- _leftButtonHeld = false;
- _startSelectionDrag = false;
- }
- else
- {
- ClearLeftMouseStates();
- }
+ ClearLeftMouseStates();
}
if (e.Button == MouseButtons.Right)
@@ -1070,10 +1080,6 @@ private void TasView_PointedCellChanged(object sender, InputRoll.CellEventArgs e
{
if (!TasView.IsRowSelected(i))
TasView.SelectRow(i, _selectionDragState);
- if (AxisEditingMode && ModifierKeys is Keys.Control or Keys.Shift)
- {
- _extraAxisRows.SetMembership(i, shouldBeMember: _selectionDragState);
- }
}
SetSplicer();
@@ -1266,19 +1272,14 @@ private void AxisPaint(int frame, int startVal, int endVal)
private void TasView_MouseMove(object sender, MouseEventArgs e)
{
// For axis editing
- if (AxisEditingMode)
+ if (_axisEditYPos == -1)
{
- int increment = (_axisEditYPos - e.Y) / 4;
- if (_axisEditYPos == -1)
- {
- return;
- }
-
- var value = (_axisPaintState + increment).ConstrainWithin(ControllerType.Axes[_axisEditColumn].Range);
- CurrentTasMovie.SetAxisState(_axisEditRow, _axisEditColumn, value);
- _axisTypedValue = value.ToString();
- RefreshDialog();
+ return;
}
+
+ int increment = (_axisEditYPos - e.Y) / 4;
+ AnalogChangeBy(increment);
+ _axisEditYPos -= increment * 4;
}
private void TasView_SelectedIndexChanged(object sender, EventArgs e)
@@ -1288,50 +1289,74 @@ private void TasView_SelectedIndexChanged(object sender, EventArgs e)
public void AnalogIncrementByOne()
{
- if (AxisEditingMode)
- {
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Up));
- }
+ AnalogChangeBy(1);
}
public void AnalogDecrementByOne()
{
- if (AxisEditingMode)
- {
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Down));
- }
+ AnalogChangeBy(-1);
}
public void AnalogIncrementByTen()
{
- if (AxisEditingMode)
- {
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Up | Keys.Shift));
- }
+ AnalogChangeBy(10);
}
public void AnalogDecrementByTen()
{
- if (AxisEditingMode)
+ AnalogChangeBy(-10);
+ }
+
+ private void AnalogChangeBy(int change)
+ {
+ if (!AxisEditingMode) return;
+
+ if (_didAxisType)
{
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Down | Keys.Shift));
+ _didAxisType = false;
+ CurrentTasMovie.ChangeLog.EndBatch();
}
+
+ bool batch = CurrentTasMovie.ChangeLog.BeginNewBatch($"Axis change by {change}, frame {TasView.SelectedRows.First()}", true);
+ CurrentTasMovie.SingleInvalidation(() =>
+ {
+ foreach (int frame in TasView.SelectedRows)
+ {
+ int value = CurrentTasMovie.GetAxisState(frame, AxisEditColumn) + change;
+ value = value.ConstrainWithin(ControllerType.Axes[AxisEditColumn].Range);
+ CurrentTasMovie.SetAxisState(frame, AxisEditColumn, value);
+ _axisTypedValue = value.ToString(); // Typing with multiple rows selected has undefined behavior if the values do not all match.
+ }
+ });
+ if (batch) CurrentTasMovie.ChangeLog.EndBatch();
+
+ RefreshDialog();
}
public void AnalogMax()
{
- if (AxisEditingMode)
+ if (!AxisEditingMode) return;
+
+ int value = ControllerType.Axes[AxisEditColumn].Max;
+ foreach (int frame in TasView.SelectedRows)
{
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Right));
+ CurrentTasMovie.SetAxisState(frame, AxisEditColumn, value);
}
+ _axisTypedValue = value.ToString();
+ RefreshDialog();
}
public void AnalogMin()
{
- if (AxisEditingMode)
+ if (!AxisEditingMode) return;
+
+ int value = ControllerType.Axes[AxisEditColumn].Min;
+ foreach (int frame in TasView.SelectedRows)
{
- EditAnalogProgrammatically(new KeyEventArgs(Keys.Left));
+ CurrentTasMovie.SetAxisState(frame, AxisEditColumn, value);
}
+ _axisTypedValue = value.ToString();
+ RefreshDialog();
}
public void EditAnalogProgrammatically(KeyEventArgs e)
@@ -1341,146 +1366,91 @@ public void EditAnalogProgrammatically(KeyEventArgs e)
return;
}
- // TODO: properly handle axis editing batches
- BeginBatchEdit();
-
- int value = CurrentTasMovie.GetAxisState(_axisEditRow, _axisEditColumn);
string prevTyped = _axisTypedValue;
+ AxisSpec axis = ControllerType.Axes[AxisEditColumn];
- var range = ControllerType.Axes[_axisEditColumn];
-
- // feos: typing past max digits overwrites existing value, not touching the sign
- // but doesn't handle situations where the range is like -50 through 100, where minimum is negative and has less digits
- // it just uses 3 as maxDigits there too, leaving room for typing impossible values (that are still ignored by the game and then clamped)
- int maxDigits = range.MaxDigits;
- int curDigits = _axisTypedValue.Length;
- string curMinus;
- if (_axisTypedValue.StartsWith('-'))
+ int charToType = -1;
+ if (e.KeyCode is >= Keys.D0 and <= Keys.D9)
{
- curDigits -= 1;
- curMinus = "-";
+ charToType = e.KeyCode - Keys.D0;
}
- else
+ else if (e.KeyCode is >= Keys.NumPad0 and <= Keys.NumPad9)
{
- curMinus = "";
+ charToType = e.KeyCode - Keys.NumPad0;
}
- if (e.KeyCode == Keys.Right)
+ if (charToType != -1)
{
- value = range.Max;
- _axisTypedValue = value.ToString(NumberFormatInfo.InvariantInfo);
- }
- else if (e.KeyCode == Keys.Left)
- {
- value = range.Min;
- _axisTypedValue = value.ToString(NumberFormatInfo.InvariantInfo);
- }
- else if (e.KeyCode is >= Keys.D0 and <= Keys.D9)
- {
- if (curDigits >= maxDigits)
+ if ((_axisTypedValue.StartsWith('-') && _axisTypedValue.Length < axis.Min.ToString().Length)
+ || (!_axisTypedValue.StartsWith('-') && _axisTypedValue.Length < axis.Max.ToString().Length))
{
- _axisTypedValue = curMinus;
+ _axisTypedValue += charToType;
}
-
- _axisTypedValue += e.KeyCode - Keys.D0;
}
- else if (e.KeyCode is >= Keys.NumPad0 and <= Keys.NumPad9)
+ else if (e.KeyCode is Keys.OemMinus or Keys.Subtract)
{
- if (curDigits >= maxDigits)
+ if (axis.Min < 0)
{
- _axisTypedValue = curMinus;
+ _axisTypedValue = _axisTypedValue.StartsWith('-')
+ ? _axisTypedValue.Substring(startIndex: 1)
+ : $"-{_axisTypedValue}";
}
-
- _axisTypedValue += e.KeyCode - Keys.NumPad0;
- }
- else if (e.KeyCode is Keys.OemMinus or Keys.Subtract)
- {
- _axisTypedValue = _axisTypedValue.StartsWith('-')
- ? _axisTypedValue.Substring(startIndex: 1)
- : $"-{_axisTypedValue}";
}
else if (e.KeyCode == Keys.Back)
{
- if (_axisTypedValue.Length is 0) // Very first key press is backspace?
+ if (!_didAxisType)
{
- _axisTypedValue = value.ToString(NumberFormatInfo.InvariantInfo);
+ _axisTypedValue = CurrentTasMovie.GetAxisState(TasView.SelectedRows.First(), AxisEditColumn).ToString();
+ _didAxisType = true;
+ }
+ if (_axisTypedValue.Length != 0)
+ {
+ _axisTypedValue = _axisTypedValue.Substring(startIndex: 0, length: _axisTypedValue.Length - 1); // drop last char
}
-
- _axisTypedValue = _axisTypedValue.Substring(startIndex: 0, length: _axisTypedValue.Length - 1); // drop last char
- if (!int.TryParse(_axisTypedValue, out value)) value = 0;
}
else if (e.KeyCode == Keys.Enter)
{
- _axisEditYPos = -1;
- AxisEditRow = -1;
+ AxisEditColumn = null;
}
else if (e.KeyCode == Keys.Escape)
{
- _axisEditYPos = -1;
-
- if (_axisBackupState != _axisPaintState)
- {
- CurrentTasMovie.SetAxisState(_axisEditRow, _axisEditColumn, _axisBackupState);
- }
-
- AxisEditRow = -1;
+ AxisEditColumn = null;
+ CurrentTasMovie.ChangeLog.Undo(_axisRestoreId);
}
- else
- {
- int changeBy = 0;
- if (e.KeyCode == Keys.Up)
- {
- changeBy = 1;
- }
- else if (e.KeyCode == Keys.Down)
- {
- changeBy = -1;
- }
- if (e.Modifiers == Keys.Shift)
- {
- changeBy *= 10;
- }
-
- value += changeBy;
- if (changeBy != 0)
- {
- _axisTypedValue = value.ToString(NumberFormatInfo.InvariantInfo);
- }
- }
-
- if (!AxisEditingMode)
- {
- CurrentTasMovie.ChangeLog.EndBatch();
- }
- else
+ if (_axisTypedValue != prevTyped)
{
+ CurrentTasMovie.ChangeLog.BeginNewBatch($"Axis edit: {TasView.SelectedRows.First()}", true);
+ _didAxisType = true;
+
+ int value;
if (_axisTypedValue.Length is 0)
{
- if (prevTyped.Length is not 0)
- {
- value = ControllerType.Axes[_axisEditColumn].Neutral;
- CurrentTasMovie.SetAxisState(_axisEditRow, _axisEditColumn, value);
- }
+ value = axis.Neutral;
}
else
{
if (int.TryParse(_axisTypedValue, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out value)) // String "-" can't be parsed.
{
- value = value.ConstrainWithin(range.Range);
-
- CurrentTasMovie.SetAxisState(_axisEditRow, _axisEditColumn, value);
+ value = value.ConstrainWithin(axis.Range);
+ }
+ else
+ {
+ value = 0;
}
}
- foreach (int row in _extraAxisRows)
+ CurrentTasMovie.SingleInvalidation(() =>
{
- CurrentTasMovie.SetAxisState(row, _axisEditColumn, value);
- }
+ foreach (int row in TasView.SelectedRows)
+ {
+ CurrentTasMovie.SetAxisState(row, AxisEditColumn, value);
+ }
+ });
}
- bool didRefresh = EndBatchEdit();
- if (!didRefresh && (prevTyped != _axisTypedValue || !AxisEditingMode))
+ // We (probably) need a refresh if the typed value changed or we've exited axis editing mode.
+ if (prevTyped != _axisTypedValue || !AxisEditingMode)
{
RefreshDialog();
}
@@ -1498,11 +1468,7 @@ private void TasView_KeyDown(object sender, KeyEventArgs e)
GoToFrame(CurrentTasMovie.InputLogLength-1);
}
- if (AxisEditingMode
- && e.KeyCode != Keys.Right
- && e.KeyCode != Keys.Left
- && e.KeyCode != Keys.Up
- && e.KeyCode != Keys.Down)
+ if (AxisEditingMode)
{
EditAnalogProgrammatically(e);
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
index e5824157dbd..e763b4bbda7 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs
@@ -168,6 +168,7 @@ public TAStudio()
TasView.QueryRowBkColor += TasView_QueryRowBkColor;
TasView.QueryItemIcon += TasView_QueryItemIcon;
TasView.QueryFrameLag += TasView_QueryFrameLag;
+ TasView.QueryShouldSelectCell += TasView_QueryShouldSelect;
TasView.PointedCellChanged += TasView_PointedCellChanged;
TasView.MouseLeave += TAStudio_MouseLeave;