Refactors for selection in `InputRoll`

also standardises behaviour of Select All and Insert Separator buttons
see e88fa8135
This commit is contained in:
YoshiRulz 2022-06-30 00:17:49 +10:00
parent 5875df4b76
commit 206dcaf49b
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
16 changed files with 189 additions and 294 deletions

View File

@ -46,6 +46,9 @@ namespace BizHawk.Client.Common
public int ActiveCount => _cheatList.Count(c => c.Enabled);
public bool AnyActive
=> _cheatList.Any(static c => c.Enabled);
public bool Changes
{
get => _changes;

View File

@ -586,6 +586,12 @@ namespace BizHawk.Client.EmuHawk
Refresh();
}
public void ToggleSelectAll()
{
if (SelectedRows.Count() == RowCount) DeselectAll();
else SelectAll();
}
public void TruncateSelection(int index)
{
_selectedItems.RemoveWhere(cell => cell.RowIndex > index);
@ -596,17 +602,17 @@ namespace BizHawk.Client.EmuHawk
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsPointingAtColumnHeader => IsHoveringOnColumnCell;
/// <returns>the <see cref="Cell.RowIndex"/> of the selected row with the earliest index, or <see langword="null"/> if no rows are selected</returns>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int? FirstSelectedIndex => AnyRowsSelected
? SelectedRows.Min()
: (int?)null;
public int? SelectionStartIndex
=> AnyRowsSelected ? SelectedRowsWithDuplicates.Min() : null;
/// <returns>the <see cref="Cell.RowIndex"/> of the selected row with the latest index, or <see langword="null"/> if no rows are selected</returns>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int? LastSelectedIndex => AnyRowsSelected
? SelectedRows.Max()
: (int?)null;
public int? SelectionEndIndex
=> AnyRowsSelected ? SelectedRowsWithDuplicates.Max() : null;
/// <summary>
/// Gets or sets the current Cell that the mouse was in.
@ -919,13 +925,26 @@ namespace BizHawk.Client.EmuHawk
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IEnumerable<int> SelectedRows => _selectedItems
.Where(cell => cell.RowIndex.HasValue)
.Select(cell => cell.RowIndex.Value)
.Distinct();
private IEnumerable<int> SelectedRowsWithDuplicates
=> _selectedItems.Where(static cell => cell.RowIndex is not null).Select(static cell => cell.RowIndex.Value);
public bool AnyRowsSelected => _selectedItems.Any(cell => cell.RowIndex.HasValue);
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IEnumerable<int> SelectedRows
=> SelectedRowsWithDuplicates.Distinct();
[Browsable(false)]
public bool AnyRowsSelected
=> _selectedItems.Any(static cell => cell.RowIndex is not null);
/// <returns>the <see cref="Cell.RowIndex"/> of the first row in the selection list (throws if no rows are selected)</returns>
/// <remarks>you probably want <see cref="SelectionStartIndex"/>, TODO check existing callsites</remarks>
[Browsable(false)]
public int FirstSelectedRowIndex
=> SelectedRowsWithDuplicates.First();
public bool IsRowSelected(int rowIndex)
=> _selectedItems.Any(cell => cell.RowIndex == rowIndex);
public IEnumerable<ToolStripItem> GenerateContextMenuItems()
{
@ -1356,7 +1375,7 @@ namespace BizHawk.Client.EmuHawk
{
if (ChangeSelectionWhenPaging)
{
var selectedRow = SelectedRows.Any() ? SelectedRows.First() : FirstVisibleRow;
var selectedRow = AnyRowsSelected ? FirstSelectedRowIndex : FirstVisibleRow;
var increment = LastVisibleRow - FirstVisibleRow;
var newSelectedRow = selectedRow - increment;
if (newSelectedRow < 0)
@ -1378,7 +1397,7 @@ namespace BizHawk.Client.EmuHawk
{
if (ChangeSelectionWhenPaging)
{
var selectedRow = SelectedRows.Any() ? SelectedRows.First() : FirstVisibleRow;
var selectedRow = AnyRowsSelected ? FirstSelectedRowIndex : FirstVisibleRow;
var increment = LastVisibleRow - FirstVisibleRow;
var newSelectedRow = selectedRow + increment;
if (newSelectedRow > RowCount - 1)
@ -1412,9 +1431,9 @@ namespace BizHawk.Client.EmuHawk
}
else if (e.IsPressed(Keys.Up))
{
if (SelectedRows.Any())
if (AnyRowsSelected)
{
var selectedRow = SelectedRows.First();
var selectedRow = FirstSelectedRowIndex;
if (selectedRow > 0)
{
var targetSelectedRow = selectedRow - 1;
@ -1427,9 +1446,9 @@ namespace BizHawk.Client.EmuHawk
}
else if (e.IsPressed(Keys.Down))
{
if (SelectedRows.Any())
if (AnyRowsSelected)
{
var selectedRow = SelectedRows.First();
var selectedRow = FirstSelectedRowIndex;
if (selectedRow < RowCount - 1)
{
var targetSelectedRow = selectedRow + 1;
@ -1482,7 +1501,7 @@ namespace BizHawk.Client.EmuHawk
// Selection cursor
else if (e.IsCtrl(Keys.Up))
{
if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.First() > 0)
if (AnyRowsSelected && LetKeysModifySelection && FirstSelectedRowIndex > 0)
{
foreach (var row in SelectedRows.ToList()) // clones SelectedRows
{
@ -1493,7 +1512,7 @@ namespace BizHawk.Client.EmuHawk
}
else if (e.IsCtrl(Keys.Down))
{
if (SelectedRows.Any() && LetKeysModifySelection)
if (AnyRowsSelected && LetKeysModifySelection)
{
foreach (var row in SelectedRows.Reverse()) // clones SelectedRows
{
@ -1504,30 +1523,30 @@ namespace BizHawk.Client.EmuHawk
}
else if (e.IsCtrl(Keys.Left))
{
if (SelectedRows.Any() && LetKeysModifySelection)
if (AnyRowsSelected && LetKeysModifySelection)
{
SelectRow(SelectedRows.Last(), false);
}
}
else if (e.IsCtrl(Keys.Right))
{
if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.Last() < _rowCount - 1)
if (AnyRowsSelected && LetKeysModifySelection && SelectedRows.Last() < _rowCount - 1)
{
SelectRow(SelectedRows.Last() + 1, true);
}
}
else if (e.IsCtrlShift(Keys.Left))
{
if (SelectedRows.Any() && LetKeysModifySelection && SelectedRows.First() > 0)
if (AnyRowsSelected && LetKeysModifySelection && FirstSelectedRowIndex > 0)
{
SelectRow(SelectedRows.First() - 1, true);
SelectRow(FirstSelectedRowIndex - 1, true);
}
}
else if (e.IsCtrlShift(Keys.Right))
{
if (SelectedRows.Any() && LetKeysModifySelection)
if (AnyRowsSelected && LetKeysModifySelection)
{
SelectRow(SelectedRows.First(), false);
SelectRow(FirstSelectedRowIndex, false);
}
}
else if (e.IsCtrl(Keys.PageUp))

View File

@ -1462,7 +1462,7 @@ namespace BizHawk.Client.EmuHawk
public void UpdateCheatStatus()
{
if (CheatList.ActiveCount > 0)
if (CheatList.AnyActive)
{
CheatStatusButton.ToolTipText = "Cheats are currently active";
CheatStatusButton.Image = Properties.Resources.Freeze;

View File

@ -384,10 +384,11 @@ namespace BizHawk.Client.EmuHawk
MoveUpMenuItem.Enabled =
MoveDownMenuItem.Enabled =
ToggleMenuItem.Enabled =
SelectedIndices.Any();
CheatListView.AnyRowsSelected;
// Always leave enabled even if no cheats enabled. This way the hotkey will always work however a new cheat is enabled
// DisableAllCheatsMenuItem.Enabled = MainForm.CheatList.ActiveCount > 0;
#if false // Always leave enabled even if no cheats enabled. This way the hotkey will always work, even if a new cheat is enabled without also refreshing the menu
DisableAllCheatsMenuItem.Enabled = MainForm.CheatList.AnyActive;
#endif
GameGenieSeparator.Visible =
OpenGameGenieEncoderDecoderMenuItem.Visible =
@ -411,15 +412,7 @@ namespace BizHawk.Client.EmuHawk
private void InsertSeparatorMenuItem_Click(object sender, EventArgs e)
{
if (SelectedIndices.Any())
{
MainForm.CheatList.Insert(SelectedIndices.Max(), Cheat.Separator);
}
else
{
MainForm.CheatList.Add(Cheat.Separator);
}
MainForm.CheatList.Insert(CheatListView.SelectionStartIndex ?? MainForm.CheatList.Count, Cheat.Separator);
GeneralUpdate();
UpdateMessageLabel();
}
@ -480,9 +473,7 @@ namespace BizHawk.Client.EmuHawk
}
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
CheatListView.SelectAll();
}
=> CheatListView.ToggleSelectAll();
private void ToggleMenuItem_Click(object sender, EventArgs e)
{
@ -606,7 +597,7 @@ namespace BizHawk.Client.EmuHawk
RemoveContextMenuItem.Enabled =
SelectedCheats.Any();
DisableAllContextMenuItem.Enabled = MainForm.CheatList.ActiveCount > 0;
DisableAllContextMenuItem.Enabled = MainForm.CheatList.AnyActive;
}
private void ViewInHexEditorContextMenuItem_Click(object sender, EventArgs e)

View File

@ -209,25 +209,13 @@ namespace BizHawk.Client.EmuHawk
private void CopySelectedDisassembler()
{
var indices = DisassemblerView.SelectedRows.ToList();
if (indices.Count > 0)
if (!DisassemblerView.AnyRowsSelected) return;
StringBuilder blob = new();
foreach (var line in DisassemblerView.SelectedRows.Select(i => _disassemblyLines[i]))
{
var blob = new StringBuilder();
foreach (int index in indices)
{
if (blob.Length != 0)
{
blob.AppendLine();
}
blob.Append(_disassemblyLines[index].Address.ToHexString(_pcRegisterSize))
.Append(' ')
.Append(_disassemblyLines[index].Mnemonic);
}
Clipboard.SetDataObject(blob.ToString());
blob.AppendFormat("{0} {1}\n", line.Address.ToHexString(_pcRegisterSize), line.Mnemonic);
}
Clipboard.SetDataObject(blob.ToString());
}
private void OnPauseChanged(bool isPaused)
@ -237,16 +225,14 @@ namespace BizHawk.Client.EmuHawk
private void DisassemblerContextMenu_Opening(object sender, EventArgs e)
{
AddBreakpointContextMenuItem.Enabled = DisassemblerView.SelectedRows.Any();
AddBreakpointContextMenuItem.Enabled = DisassemblerView.AnyRowsSelected;
}
private void AddBreakpointContextMenuItem_Click(object sender, EventArgs e)
{
var indices = DisassemblerView.SelectedRows.ToList();
if (indices.Count > 0)
if (DisassemblerView.AnyRowsSelected)
{
var line = _disassemblyLines[indices[0]];
var line = _disassemblyLines[DisassemblerView.FirstSelectedRowIndex];
BreakPointControl1.AddBreakpoint(line.Address, 0xFFFFFFFF, Emulation.Common.MemoryCallbackType.Execute);
}
}

View File

@ -1991,7 +1991,7 @@ namespace BizHawk.Client.EmuHawk
(_highlightedAddress.HasValue || _secondaryHighlightedAddresses.Any()) &&
_domain.Writable;
UnfreezeAllContextItem.Visible = MainForm.CheatList.ActiveCount > 0;
UnfreezeAllContextItem.Visible = MainForm.CheatList.AnyActive;
PasteContextItem.Visible = _domain.Writable && data != null && data.GetDataPresent(DataFormats.Text);
ContextSeparator1.Visible =

View File

@ -829,7 +829,7 @@ namespace BizHawk.Client.EmuHawk
DuplicateScriptMenuItem.Enabled =
MoveUpMenuItem.Enabled =
MoveDownMenuItem.Enabled =
LuaListView.SelectedRows.Any();
LuaListView.AnyRowsSelected;
SelectAllMenuItem.Enabled = LuaImp.ScriptList.Any();
StopAllScriptsMenuItem.Enabled = LuaImp.ScriptList.Any(script => script.Enabled);
@ -986,7 +986,7 @@ namespace BizHawk.Client.EmuHawk
private void DuplicateScriptMenuItem_Click(object sender, EventArgs e)
{
if (LuaListView.SelectedRows.Any())
if (LuaListView.AnyRowsSelected)
{
var script = SelectedItems.First();
@ -1024,16 +1024,7 @@ namespace BizHawk.Client.EmuHawk
private void InsertSeparatorMenuItem_Click(object sender, EventArgs e)
{
var indices = LuaListView.SelectedRows.ToList();
if (indices.Any() && indices.Last() < LuaImp.ScriptList.Count)
{
LuaImp.ScriptList.Insert(indices.Last(), LuaFile.SeparatorInstance);
}
else
{
LuaImp.ScriptList.Add(LuaFile.SeparatorInstance);
}
LuaImp.ScriptList.Insert(LuaListView.SelectionStartIndex ?? LuaImp.ScriptList.Count, LuaFile.SeparatorInstance);
UpdateDialog();
}
@ -1090,9 +1081,7 @@ namespace BizHawk.Client.EmuHawk
}
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
LuaListView.SelectAll();
}
=> LuaListView.ToggleSelectAll();
private void StopAllScriptsMenuItem_Click(object sender, EventArgs e)
{

View File

@ -170,9 +170,8 @@ namespace BizHawk.Client.EmuHawk
MainForm.UpdateStatusSlots();
}
public TasBranch SelectedBranch => BranchView.AnyRowsSelected
? Branches[BranchView.SelectedRows.First()]
: null;
public TasBranch SelectedBranch
=> BranchView.AnyRowsSelected ? Branches[BranchView.FirstSelectedRowIndex] : null;
private TasBranch CreateBranch()
{
@ -214,8 +213,7 @@ namespace BizHawk.Client.EmuHawk
{
if (SelectedBranch != null)
{
int index = BranchView.SelectedRows.First();
Branches.Current = index;
Branches.Current = BranchView.FirstSelectedRowIndex;
LoadBranch(SelectedBranch);
BranchView.Refresh();
Tastudio.MainForm.AddOnScreenMessage($"Loaded branch {Branches.Current + 1}");
@ -267,7 +265,7 @@ namespace BizHawk.Client.EmuHawk
if (BranchView.AnyRowsSelected)
{
LoadSelectedBranch();
LoadedCallback?.Invoke(BranchView.SelectedRows.First());
LoadedCallback?.Invoke(BranchView.FirstSelectedRowIndex);
}
}
@ -278,7 +276,7 @@ namespace BizHawk.Client.EmuHawk
return;
}
Branches.Current = BranchView.SelectedRows.First();
Branches.Current = BranchView.FirstSelectedRowIndex;
_backupBranch = SelectedBranch.Clone();
UndoBranchToolStripMenuItem.Enabled = UndoBranchButton.Enabled = true;
@ -300,7 +298,7 @@ namespace BizHawk.Client.EmuHawk
return;
}
int index = BranchView.SelectedRows.First();
var index = BranchView.FirstSelectedRowIndex;
string oldText = SelectedBranch.UserText;
if (EditBranchTextPopUp(index))
@ -318,14 +316,7 @@ namespace BizHawk.Client.EmuHawk
private void JumpToBranchToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!BranchView.AnyRowsSelected)
{
return;
}
int index = BranchView.SelectedRows.First();
var branch = Branches[index];
Tastudio.GoToFrame(branch.Frame);
if (BranchView.AnyRowsSelected) Tastudio.GoToFrame(Branches[BranchView.FirstSelectedRowIndex].Frame);
}
private void RemoveBranchToolStripMenuItem_Click(object sender, EventArgs e)
@ -491,7 +482,7 @@ namespace BizHawk.Client.EmuHawk
return;
}
int sel = BranchView.SelectedRows.First();
var sel = BranchView.FirstSelectedRowIndex;
if (next)
{
if (Branches[sel + 1] != null)

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
@ -17,6 +16,9 @@ namespace BizHawk.Client.EmuHawk
public IDialogController DialogController => Tastudio.MainForm;
private TasMovieMarker FirstSelectedMarker
=> Markers[MarkerView.FirstSelectedRowIndex];
public MarkerControl()
{
InitializeComponent();
@ -122,7 +124,7 @@ namespace BizHawk.Client.EmuHawk
{
EditMarkerToolStripMenuItem.Enabled =
RemoveMarkerToolStripMenuItem.Enabled =
MarkerInputRoll.AnyRowsSelected && MarkerView.SelectedRows.First() != 0;
MarkerInputRoll.AnyRowsSelected && MarkerView.FirstSelectedRowIndex is not 0;
JumpToMarkerToolStripMenuItem.Enabled =
ScrollToMarkerToolStripMenuItem.Enabled =
@ -133,29 +135,19 @@ namespace BizHawk.Client.EmuHawk
{
if (MarkerView.AnyRowsSelected)
{
Tastudio.SetVisibleFrame(SelectedMarkerFrame());
Tastudio.SetVisibleFrame(FirstSelectedMarker.Frame);
Tastudio.RefreshDialog();
}
}
private void JumpToMarkerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MarkerView.AnyRowsSelected)
{
var index = MarkerView.SelectedRows.First();
var marker = Markers[index];
Tastudio.GoToFrame(marker.Frame);
}
if (MarkerView.AnyRowsSelected) Tastudio.GoToFrame(FirstSelectedMarker.Frame);
}
private void EditMarkerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MarkerView.AnyRowsSelected)
{
var index = MarkerView.SelectedRows.First();
var marker = Markers[index];
EditMarkerPopUp(marker);
}
if (MarkerView.AnyRowsSelected) EditMarkerPopUp(FirstSelectedMarker);
}
private void AddMarkerToolStripMenuItem_Click(object sender, EventArgs e)
@ -170,12 +162,10 @@ namespace BizHawk.Client.EmuHawk
private void RemoveMarkerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MarkerView.AnyRowsSelected)
{
SelectedMarkers.ForEach(i => Markers.Remove(i));
MarkerView.RowCount = Markers.Count;
Tastudio.RefreshDialog();
}
if (!MarkerView.AnyRowsSelected) return;
foreach (var i in MarkerView.SelectedRows.Select(index => Markers[index]).ToList()) Markers.Remove(i);
MarkerView.RowCount = Markers.Count;
Tastudio.RefreshDialog();
}
public void UpdateMarkerCount()
@ -283,41 +273,18 @@ namespace BizHawk.Client.EmuHawk
{
EditMarkerButton.Enabled =
RemoveMarkerButton.Enabled =
MarkerInputRoll.AnyRowsSelected && MarkerView.SelectedRows.First() != 0;
MarkerInputRoll.AnyRowsSelected && MarkerView.FirstSelectedRowIndex is not 0;
JumpToMarkerButton.Enabled =
ScrollToMarkerButton.Enabled =
MarkerInputRoll.AnyRowsSelected;
}
private List<TasMovieMarker> SelectedMarkers => MarkerView
.SelectedRows
.Select(index => Markers[index])
.ToList();
// SuuperW: Marker renaming can be done with a right-click.
// A much more useful feature would be to easily jump to it.
private void MarkerView_MouseDoubleClick(object sender, EventArgs e)
{
if (MarkerView.AnyRowsSelected)
{
var index = MarkerView.SelectedRows.First();
var marker = Markers[index];
Tastudio.GoToFrame(marker.Frame);
}
}
public int SelectedMarkerFrame()
{
if (MarkerView.AnyRowsSelected)
{
var index = MarkerView.SelectedRows.First();
var marker = Markers[index];
return marker.Frame;
}
return -1;
if (MarkerView.AnyRowsSelected) Tastudio.GoToFrame(FirstSelectedMarker.Frame);
}
}
}

View File

@ -377,11 +377,11 @@ namespace BizHawk.Client.EmuHawk
if (columnName == FrameColumnName)
{
CurrentTasMovie.Markers.Add(TasView.LastSelectedIndex.Value, "");
CurrentTasMovie.Markers.Add(TasView.SelectionEndIndex!.Value, "");
}
else if (columnName != CursorColumnName)
{
int frame = TasView.SelectedRows.FirstOrDefault();
var frame = TasView.AnyRowsSelected ? TasView.FirstSelectedRowIndex : 0;
string buttonName = TasView.CurrentCell.Column.Name;
if (ControllerType.BoolButtons.Contains(buttonName))
@ -566,7 +566,7 @@ namespace BizHawk.Client.EmuHawk
_extraAxisRows.Clear();
_extraAxisRows.AddRange(TasView.SelectedRows);
_startSelectionDrag = true;
_selectionDragState = TasView.SelectedRows.Contains(frame);
_selectionDragState = TasView.IsRowSelected(frame);
return;
}
if (_axisEditColumn != buttonName
@ -608,7 +608,7 @@ namespace BizHawk.Client.EmuHawk
else
{
_startSelectionDrag = true;
_selectionDragState = TasView.SelectedRows.Contains(frame);
_selectionDragState = TasView.IsRowSelected(frame);
}
}
else if (TasView.CurrentCell.Column.Type != ColumnType.Text) // User changed input
@ -637,12 +637,12 @@ namespace BizHawk.Client.EmuHawk
else if (ModifierKeys == Keys.Shift && ModifierKeys != Keys.Alt)
{
if (!TasView.AnyRowsSelected) return;
int firstSel = TasView.SelectedRows.First();
var firstSel = TasView.FirstSelectedRowIndex;
if (frame <= firstSel)
{
firstSel = frame;
frame = TasView.SelectedRows.First();
frame = TasView.FirstSelectedRowIndex;
}
bool allPressed = true;
@ -729,13 +729,13 @@ namespace BizHawk.Client.EmuHawk
_rightClickControl = (ModifierKeys | Keys.Control) == ModifierKeys;
_rightClickShift = (ModifierKeys | Keys.Shift) == ModifierKeys;
_rightClickAlt = (ModifierKeys | Keys.Alt) == ModifierKeys;
if (TasView.SelectedRows.Contains(frame))
if (TasView.IsRowSelected(frame))
{
_rightClickInput = new string[TasView.SelectedRows.Count()];
_rightClickFrame = TasView.FirstSelectedIndex.Value;
_rightClickFrame = TasView.SelectionStartIndex!.Value;
try
{
CurrentTasMovie.GetLogEntries().CopyTo(_rightClickFrame, _rightClickInput, 0, TasView.SelectedRows.Count());
CurrentTasMovie.GetLogEntries().CopyTo(_rightClickFrame, _rightClickInput, 0, _rightClickInput.Length);
}
catch { }
if (_rightClickControl && _rightClickShift)
@ -817,10 +817,10 @@ namespace BizHawk.Client.EmuHawk
private void TasView_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right && !TasView.IsPointingAtColumnHeader &&
!_suppressContextMenu && TasView.SelectedRows.Any() && !_leftButtonHeld)
if (e.Button == MouseButtons.Right && !TasView.IsPointingAtColumnHeader
&& !_suppressContextMenu && !_leftButtonHeld && TasView.AnyRowsSelected)
{
if (CurrentTasMovie.FrameCount < TasView.SelectedRows.Max())
if (CurrentTasMovie.FrameCount < TasView.SelectionEndIndex)
{
// trying to be smart here
// if a loaded branch log is shorter than selection, keep selection until you attempt to call context menu

View File

@ -54,13 +54,7 @@ namespace BizHawk.Client.EmuHawk
{
if (SaveRamEmulator.CloneSaveRam() != null)
{
int index = 0;
if (TasView.SelectedRows.Any())
{
index = TasView.SelectedRows.First();
}
GoToFrame(index);
GoToFrame(TasView.AnyRowsSelected ? TasView.FirstSelectedRowIndex : 0);
var newProject = CurrentTasMovie.ConvertToSaveRamAnchoredMovie(
SaveRamEmulator.CloneSaveRam());
MainForm.PauseEmulator();
@ -224,7 +218,7 @@ namespace BizHawk.Client.EmuHawk
return;
}
if (TasView.LastSelectedIndex == CurrentTasMovie.InputLogLength)
if (TasView.SelectionEndIndex == CurrentTasMovie.InputLogLength)
{
TasView.SelectRow(CurrentTasMovie.InputLogLength, false);
}
@ -238,12 +232,13 @@ namespace BizHawk.Client.EmuHawk
if (file != null)
{
var selectionStart = TasView.SelectionStartIndex!.Value;
new MovieZone(
Emulator,
Tools,
MovieSession,
TasView.FirstSelectedIndex.Value,
TasView.LastSelectedIndex.Value - TasView.FirstSelectedIndex.Value + 1)
start: selectionStart,
length: TasView.SelectionEndIndex!.Value - selectionStart + 1)
.Save(file.FullName);
Config.RecentMacros.Add(file.FullName);
@ -406,6 +401,7 @@ namespace BizHawk.Client.EmuHawk
TasView.Refresh();
}
/// <remarks>TODO merge w/ Deselect?</remarks>
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
TasView.SelectAll();
@ -416,8 +412,9 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
var prevMarker = CurrentTasMovie.Markers.PreviousOrCurrent(TasView.LastSelectedIndex ?? 0);
var nextMarker = CurrentTasMovie.Markers.Next(TasView.LastSelectedIndex ?? 0);
var selectionEnd = TasView.SelectionEndIndex ?? 0;
var prevMarker = CurrentTasMovie.Markers.PreviousOrCurrent(selectionEnd);
var nextMarker = CurrentTasMovie.Markers.Next(selectionEnd);
int prev = prevMarker?.Frame ?? 0;
int next = nextMarker?.Frame ?? CurrentTasMovie.InputLogLength;
@ -499,7 +496,7 @@ namespace BizHawk.Client.EmuHawk
_tasClipboard.Add(new TasClipboardEntry(i, line));
}
var rollbackFrame = CurrentTasMovie.CopyOverInput(TasView.FirstSelectedIndex ?? 0, _tasClipboard.Select(x => x.ControllerState));
var rollbackFrame = CurrentTasMovie.CopyOverInput(TasView.SelectionStartIndex ?? 0, _tasClipboard.Select(static x => x.ControllerState));
if (rollbackFrame > 0)
{
GoToLastEmulatedFrameIfNecessary(rollbackFrame);
@ -539,11 +536,12 @@ namespace BizHawk.Client.EmuHawk
_tasClipboard.Add(new TasClipboardEntry(i, line));
}
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
CurrentTasMovie.InsertInput(TasView.FirstSelectedIndex ?? 0, _tasClipboard.Select(x => x.ControllerState));
var selectionStart = TasView.SelectionStartIndex;
var needsToRollback = selectionStart < Emulator.Frame;
CurrentTasMovie.InsertInput(selectionStart ?? 0, _tasClipboard.Select(static x => x.ControllerState));
if (needsToRollback)
{
GoToLastEmulatedFrameIfNecessary(TasView.FirstSelectedIndex.Value);
GoToLastEmulatedFrameIfNecessary(selectionStart!.Value);
DoAutoRestore();
}
@ -558,8 +556,9 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var rollBackFrame = TasView.FirstSelectedIndex ?? 0;
var selectionStart = TasView.SelectionStartIndex;
var needsToRollback = selectionStart < Emulator.Frame;
var rollBackFrame = selectionStart ?? 0;
_tasClipboard.Clear();
var list = TasView.SelectedRows.ToArray();
@ -598,9 +597,9 @@ namespace BizHawk.Client.EmuHawk
{
var firstWithInput = FirstNonEmptySelectedFrame;
bool needsToRollback = firstWithInput.HasValue && firstWithInput < Emulator.Frame;
int rollBackFrame = TasView.FirstSelectedIndex ?? 0;
var rollBackFrame = TasView.SelectionStartIndex ?? 0;
CurrentTasMovie.ChangeLog.BeginNewBatch($"Clear frames {TasView.SelectedRows.Min()}-{TasView.SelectedRows.Max()}");
CurrentTasMovie.ChangeLog.BeginNewBatch($"Clear frames {TasView.SelectionStartIndex}-{TasView.SelectionEndIndex}");
foreach (int frame in TasView.SelectedRows)
{
CurrentTasMovie.ClearFrame(frame);
@ -622,8 +621,9 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var rollBackFrame = TasView.FirstSelectedIndex ?? 0;
var selectionStart = TasView.SelectionStartIndex;
var needsToRollback = selectionStart < Emulator.Frame;
var rollBackFrame = selectionStart ?? 0;
if (rollBackFrame >= CurrentTasMovie.InputLogLength)
{
// Cannot delete non-existent frames
@ -665,8 +665,8 @@ namespace BizHawk.Client.EmuHawk
if (TasView.Focused && TasView.AnyRowsSelected)
{
var framesToInsert = TasView.SelectedRows;
var insertionFrame = Math.Min((TasView.LastSelectedIndex ?? 0) + 1, CurrentTasMovie.InputLogLength);
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var insertionFrame = Math.Min((TasView.SelectionEndIndex ?? 0) + 1, CurrentTasMovie.InputLogLength);
var needsToRollback = TasView.SelectionStartIndex < Emulator.Frame;
var inputLog = framesToInsert
.Select(frame => CurrentTasMovie.GetInputLogEntry(frame))
@ -689,8 +689,9 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
var insertionFrame = TasView.FirstSelectedIndex ?? 0;
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var selectionStart = TasView.SelectionStartIndex;
var insertionFrame = selectionStart ?? 0;
var needsToRollback = selectionStart < Emulator.Frame;
CurrentTasMovie.InsertEmptyFrame(insertionFrame);
@ -708,7 +709,7 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
int insertionFrame = TasView.FirstSelectedIndex ?? 0;
var insertionFrame = TasView.SelectionStartIndex ?? 0;
using var framesPrompt = new FramesPrompt();
if (framesPrompt.ShowDialog().IsOk())
{
@ -721,8 +722,8 @@ namespace BizHawk.Client.EmuHawk
{
if (TasView.Focused && TasView.AnyRowsSelected)
{
var rollbackFrame = TasView.LastSelectedIndex ?? 0;
var needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var rollbackFrame = TasView.SelectionEndIndex ?? 0;
var needsToRollback = TasView.SelectionStartIndex < Emulator.Frame;
CurrentTasMovie.Truncate(rollbackFrame);
MarkerControl.MarkerInputRoll.TruncateSelection(CurrentTasMovie.Markers.Count - 1);
@ -755,12 +756,12 @@ namespace BizHawk.Client.EmuHawk
private void SetMarkerWithTextMenuItem_Click(object sender, EventArgs e)
{
MarkerControl.AddMarker(TasView.SelectedRows.FirstOrDefault(), true);
MarkerControl.AddMarker(TasView.AnyRowsSelected ? TasView.FirstSelectedRowIndex : 0, true);
}
private void RemoveMarkersMenuItem_Click(object sender, EventArgs e)
{
CurrentTasMovie.Markers.RemoveAll(m => TasView.SelectedRows.Contains(m.Frame));
CurrentTasMovie.Markers.RemoveAll(m => TasView.IsRowSelected(m.Frame));
MarkerControl.UpdateMarkerCount();
RefreshDialog();
}
@ -1405,7 +1406,7 @@ namespace BizHawk.Client.EmuHawk
StartNewProjectFromNowMenuItem.Visible =
TasView.SelectedRows.Count() == 1
&& TasView.SelectedRows.Contains(Emulator.Frame)
&& TasView.IsRowSelected(Emulator.Frame)
&& !CurrentTasMovie.StartsFromSaveRam;
StartANewProjectFromSaveRamMenuItem.Visible =
@ -1414,7 +1415,7 @@ namespace BizHawk.Client.EmuHawk
&& !CurrentTasMovie.StartsFromSavestate;
StartFromNowSeparator.Visible = StartNewProjectFromNowMenuItem.Visible || StartANewProjectFromSaveRamMenuItem.Visible;
RemoveMarkersContextMenuItem.Enabled = CurrentTasMovie.Markers.Any(m => TasView.SelectedRows.Contains(m.Frame)); // Disable the option to remove markers if no markers are selected (FCEUX does this).
RemoveMarkersContextMenuItem.Enabled = CurrentTasMovie.Markers.Any(m => TasView.IsRowSelected(m.Frame)); // Disable the option to remove markers if no markers are selected (FCEUX does this).
CancelSeekContextMenuItem.Enabled = MainForm.PauseOnFrame.HasValue;
BranchContextMenuItem.Visible = TasView.CurrentCell?.RowIndex == Emulator.Frame;

View File

@ -686,7 +686,7 @@ namespace BizHawk.Client.EmuHawk
var loadZone = new MovieZone(path, MainForm, Emulator, MovieSession, Tools)
{
Start = TasView.FirstSelectedIndex.Value
Start = TasView.SelectionStartIndex!.Value,
};
loadZone.PlaceZone(CurrentTasMovie, Config);
}
@ -981,7 +981,8 @@ namespace BizHawk.Client.EmuHawk
private void SetSplicer()
{
// TODO: columns selected?
var temp = $"Selected: {TasView.SelectedRows.Count()} {(TasView.SelectedRows.Count() == 1 ? "frame" : "frames")}, States: {CurrentTasMovie.TasStateManager.Count}";
var selectedRowCount = TasView.SelectedRows.Count();
var temp = $"Selected: {selectedRowCount} {(selectedRowCount == 1 ? "frame" : "frames")}, States: {CurrentTasMovie.TasStateManager.Count}";
if (_tasClipboard.Any()) temp += $", Clipboard: {_tasClipboard.Count} {(_tasClipboard.Count == 1 ? "frame" : "frames")}";
SplicerStatusLabel.Text = temp;
}
@ -1014,7 +1015,7 @@ namespace BizHawk.Client.EmuHawk
{
if (insertionFrame <= CurrentTasMovie.InputLogLength)
{
bool needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var needsToRollback = TasView.SelectionStartIndex < Emulator.Frame;
CurrentTasMovie.InsertEmptyFrame(insertionFrame, numberOfFrames);
@ -1055,7 +1056,7 @@ namespace BizHawk.Client.EmuHawk
{
if (beginningFrame < CurrentTasMovie.InputLogLength)
{
bool needsToRollback = TasView.FirstSelectedIndex < Emulator.Frame;
var needsToRollback = TasView.SelectionStartIndex < Emulator.Frame;
int last = Math.Min(beginningFrame + numberOfFrames, CurrentTasMovie.InputLogLength);
for (int i = beginningFrame; i < last; i++)
{

View File

@ -1,6 +1,5 @@
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using BizHawk.Client.Common;
@ -85,9 +84,8 @@ namespace BizHawk.Client.EmuHawk
_tastudio.RefreshDialog();
}
private int SelectedItem => HistoryView.SelectedRows.Any()
? HistoryView.SelectedRows.First()
: -1;
private int SelectedItem
=> HistoryView.AnyRowsSelected ? HistoryView.FirstSelectedRowIndex : -1;
private void UndoToHere(int index)
{

View File

@ -321,17 +321,13 @@ namespace BizHawk.Client.EmuHawk
private void CopyMenuItem_Click(object sender, EventArgs e)
{
var indices = TraceView.SelectedRows.ToList();
if (indices.Count > 0)
if (!TraceView.AnyRowsSelected) return;
StringBuilder blob = new();
foreach (var info in TraceView.SelectedRows.Select(index => _instructions[index]))
{
var blob = new StringBuilder();
foreach (int index in indices)
{
blob.Append($"{_instructions[index].Disassembly} {_instructions[index].RegisterInfo}\n");
}
Clipboard.SetDataObject(blob.ToString());
blob.AppendFormat("{0} {1}\n", info.Disassembly, info.RegisterInfo);
}
Clipboard.SetDataObject(blob.ToString());
}
private void SelectAllMenuItem_Click(object sender, EventArgs e)

View File

@ -421,8 +421,7 @@ namespace BizHawk.Client.EmuHawk
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any()
&& _searches.Domain.Writable;
WatchListView.AnyRowsSelected && _searches.Domain.Writable;
}
private long? CompareToValue
@ -546,6 +545,9 @@ namespace BizHawk.Client.EmuHawk
private IEnumerable<Watch> SelectedWatches => SelectedItems.Where(x => !x.IsSeparator);
private bool MayPokeAllSelected
=> WatchListView.AnyRowsSelected && SelectedWatches.All(static w => w.Domain.Writable);
private void SetRemovedMessage(int val)
{
MessageLabel.Text = $"{val} {(val == 1 ? "address" : "addresses")} removed";
@ -876,16 +878,10 @@ namespace BizHawk.Client.EmuHawk
private void PokeAddress()
{
if (SelectedIndices.Any())
{
var poke = new RamPoke(DialogController, SelectedIndices.Select(t => _searches[t]), MainForm.CheatList)
{
InitialLocation = this.ChildPointToScreen(WatchListView)
};
this.ShowDialogWithTempMute(poke);
UpdateList();
}
if (!WatchListView.AnyRowsSelected) return;
using RamPoke poke = new(DialogController, SelectedItems, MainForm.CheatList) { InitialLocation = this.ChildPointToScreen(WatchListView) };
this.ShowDialogWithTempMute(poke);
UpdateList();
}
private void RemoveRamWatchesFromList()
@ -944,12 +940,6 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SelectAllAddresses()
{
if (SelectedIndices.Count() == WatchListView.RowCount) WatchListView.DeselectAll();
else WatchListView.SelectAll();
}
public class RamSearchSettings
{
public RamSearchSettings()
@ -1196,12 +1186,11 @@ namespace BizHawk.Client.EmuHawk
RemoveMenuItem.Enabled =
AddToRamWatchMenuItem.Enabled =
SelectedIndices.Any();
WatchListView.AnyRowsSelected;
PokeAddressMenuItem.Enabled =
FreezeAddressMenuItem.Enabled =
SelectedIndices.Any() &&
SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
UndoMenuItem.Enabled =
ClearUndoMenuItem.Enabled =
@ -1299,9 +1288,7 @@ namespace BizHawk.Client.EmuHawk
}
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
SelectAllAddresses();
}
=> WatchListView.ToggleSelectAll();
private void SettingsSubMenu_DropDownOpened(object sender, EventArgs e)
{
@ -1379,27 +1366,17 @@ namespace BizHawk.Client.EmuHawk
FreezeContextMenuItem.Visible =
ContextMenuSeparator2.Visible =
ViewInHexEditorContextMenuItem.Visible =
SelectedIndices.Any();
WatchListView.AnyRowsSelected;
PokeContextMenuItem.Enabled =
FreezeContextMenuItem.Visible =
SelectedIndices.Any() &&
SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
UnfreezeAllContextMenuItem.Visible = MainForm.CheatList.ActiveCount > 0;
UnfreezeAllContextMenuItem.Visible = MainForm.CheatList.AnyActive;
ContextMenuSeparator3.Visible = SelectedIndices.Any() || (MainForm.CheatList.ActiveCount > 0);
ContextMenuSeparator3.Visible = WatchListView.AnyRowsSelected || MainForm.CheatList.AnyActive;
var allCheats = true;
foreach (var index in SelectedIndices)
{
if (!MainForm.CheatList.IsActive(_settings.Domain, _searches[index].Address))
{
allCheats = false;
}
}
if (allCheats)
if (SelectedItems.All(watch => MainForm.CheatList.IsActive(_settings.Domain, watch.Address)))
{
FreezeContextMenuItem.Text = "&Unfreeze Address";
FreezeContextMenuItem.Image = Resources.Unfreeze;
@ -1658,12 +1635,11 @@ namespace BizHawk.Client.EmuHawk
{
RemoveToolBarItem.Enabled =
AddToRamWatchToolBarItem.Enabled =
SelectedIndices.Any();
WatchListView.AnyRowsSelected;
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any()
&& _searches.Domain.Writable;
WatchListView.AnyRowsSelected && _searches.Domain.Writable;
}
private void WatchListView_Enter(object sender, EventArgs e)
@ -1688,7 +1664,7 @@ namespace BizHawk.Client.EmuHawk
private void WatchListView_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (SelectedIndices.Any())
if (WatchListView.AnyRowsSelected)
{
AddToRamWatch();
}

View File

@ -142,6 +142,9 @@ namespace BizHawk.Client.EmuHawk
private IEnumerable<Watch> SelectedWatches => SelectedItems.Where(x => !x.IsSeparator);
private IEnumerable<Watch> SelectedSeparators => SelectedItems.Where(x => x.IsSeparator);
private bool MayPokeAllSelected
=> WatchListView.AnyRowsSelected && SelectedWatches.All(static w => w.Domain.Writable);
public IEnumerable<Watch> Watches => _watches.Where(x => !x.IsSeparator);
protected override void GeneralUpdate() => FrameUpdate();
@ -233,8 +236,7 @@ namespace BizHawk.Client.EmuHawk
GeneralUpdate();
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any()
&& SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
}
}
}
@ -507,8 +509,7 @@ namespace BizHawk.Client.EmuHawk
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any() &&
SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
}
}
@ -704,14 +705,13 @@ namespace BizHawk.Client.EmuHawk
MoveDownMenuItem.Enabled =
MoveTopMenuItem.Enabled =
MoveBottomMenuItem.Enabled =
SelectedIndices.Any();
WatchListView.AnyRowsSelected;
SplitWatchMenuItem.Enabled = MaySplitAllSelected;
PokeAddressMenuItem.Enabled =
FreezeAddressMenuItem.Enabled =
SelectedIndices.Any() &&
SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
}
private MemoryDomain _currentDomain;
@ -756,19 +756,11 @@ namespace BizHawk.Client.EmuHawk
private void RemoveWatchMenuItem_Click(object sender, EventArgs e)
{
var indices = SelectedIndices
.OrderByDescending(i => i)
.ToList();
if (indices.Any())
{
foreach (var index in indices)
{
_watches.RemoveAt(index);
}
WatchListView.RowCount = _watches.Count;
GeneralUpdate();
UpdateWatchCount();
}
if (!WatchListView.AnyRowsSelected) return;
foreach (var index in SelectedIndices.OrderByDescending(static i => i).ToList()) _watches.RemoveAt(index);
WatchListView.RowCount = _watches.Count;
GeneralUpdate();
UpdateWatchCount();
}
private void DuplicateWatchMenuItem_Click(object sender, EventArgs e)
@ -840,16 +832,7 @@ namespace BizHawk.Client.EmuHawk
private void InsertSeparatorMenuItem_Click(object sender, EventArgs e)
{
var indexes = SelectedIndices.ToList();
if (indexes.Any())
{
_watches.Insert(indexes[0], SeparatorWatch.Instance);
}
else
{
_watches.Add(SeparatorWatch.Instance);
}
_watches.Insert(WatchListView.SelectionStartIndex ?? _watches.Count, SeparatorWatch.Instance);
WatchListView.RowCount = _watches.Count;
Changes();
UpdateWatchCount();
@ -975,9 +958,7 @@ namespace BizHawk.Client.EmuHawk
}
private void SelectAllMenuItem_Click(object sender, EventArgs e)
{
WatchListView.SelectAll();
}
=> WatchListView.ToggleSelectAll();
private void SettingsSubMenu_DropDownOpened(object sender, EventArgs e)
{
@ -1051,8 +1032,7 @@ namespace BizHawk.Client.EmuHawk
UpdateStatusBar();
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any() &&
SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
}
private void ColumnToggleCallback()
@ -1072,12 +1052,11 @@ namespace BizHawk.Client.EmuHawk
}
}
private bool MaySplitAllSelected => SelectedIndices.Any() && SelectedWatches.All(static w => w.IsSplittable);
private bool MaySplitAllSelected
=> WatchListView.AnyRowsSelected && SelectedWatches.All(static w => w.IsSplittable);
private void ListViewContextMenu_Opening(object sender, CancelEventArgs e)
{
var indexes = WatchListView.SelectedRows.ToList();
EditContextMenuItem.Visible =
RemoveContextMenuItem.Visible =
DuplicateContextMenuItem.Visible =
@ -1093,7 +1072,7 @@ namespace BizHawk.Client.EmuHawk
MoveDownContextMenuItem.Visible =
MoveTopContextMenuItem.Visible =
MoveBottomContextMenuItem.Visible =
indexes.Count > 0;
WatchListView.AnyRowsSelected;
ReadBreakpointContextMenuItem.Visible =
WriteBreakpointContextMenuItem.Visible =
@ -1107,8 +1086,7 @@ namespace BizHawk.Client.EmuHawk
PokeContextMenuItem.Enabled =
FreezeContextMenuItem.Visible =
SelectedIndices.Any()
&& SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
var allCheats = SelectedWatches.All(x => MainForm.CheatList.IsActive(x.Domain, x.Address));
@ -1123,11 +1101,11 @@ namespace BizHawk.Client.EmuHawk
FreezeContextMenuItem.Image = Resources.Freeze;
}
UnfreezeAllContextMenuItem.Visible = MainForm.CheatList.ActiveCount > 0;
UnfreezeAllContextMenuItem.Visible = MainForm.CheatList.AnyActive;
ViewInHexEditorContextMenuItem.Visible = SelectedWatches.Count() == 1;
newToolStripMenuItem.Visible = indexes.Count == 0;
newToolStripMenuItem.Visible = !WatchListView.AnyRowsSelected;
}
private void UnfreezeAllContextMenuItem_Click(object sender, EventArgs e)
@ -1207,8 +1185,7 @@ namespace BizHawk.Client.EmuHawk
{
PokeAddressToolBarItem.Enabled =
FreezeAddressToolBarItem.Enabled =
SelectedIndices.Any()
&& SelectedWatches.All(w => w.Domain.Writable);
MayPokeAllSelected;
}
private void WatchListView_MouseDoubleClick(object sender, MouseEventArgs e)