From 6dcf7cf17729230d507aec2a0342428606a76044 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Wed, 17 Jun 2026 19:34:41 -0500 Subject: [PATCH 1/4] show the column text in an empty cell when hovering over it in TAStudio --- .../InputRoll/InputRoll.Drawing.cs | 28 +++++++++++++++++-- .../CustomControls/InputRoll/InputRoll.cs | 7 +++++ .../tools/TAStudio/TAStudio.ListView.cs | 9 ++---- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs index 7f0c9b82651..716a3a0e210 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs @@ -189,6 +189,7 @@ private void DrawData(List visibleColumns, int firstVisibleRow, int _renderer.PrepDrawString(Font, _foreColor); Cell currentCell = new(); + Cell mouseCell = ShowColumnTextOnHover ? CurrentCell : null; if (HorizontalOrientation) { for (int j = 0; j < visibleColumns.Count; j++) @@ -223,6 +224,7 @@ private void DrawData(List visibleColumns, int firstVisibleRow, int bool rePrep = false; Color foreColor = _foreColor; + Font font = Font; currentCell.Column = col; currentCell.RowIndex = f + startRow; if (_selectedItems.Contains(currentCell)) @@ -230,13 +232,20 @@ private void DrawData(List visibleColumns, int firstVisibleRow, int foreColor = SystemColors.HighlightText; rePrep = true; } + if (text.Length == 0 && mouseCell == currentCell) + { + font = new Font(Font, FontStyle.Regular); + foreColor = SystemColors.GrayText; + text = col.Text; + rePrep = true; + } if (col.Rotatable || rePrep) { - _renderer.PrepDrawString(Font, foreColor, rotate: col.Rotatable); + _renderer.PrepDrawString(font, foreColor, rotate: col.Rotatable); rePrep = true; } - int textWidth = (int)_renderer.MeasureString(text, Font).Width; + int textWidth = (int)_renderer.MeasureString(text, font).Width; if (col.Rotatable) { // Center Text @@ -287,13 +296,26 @@ private void DrawData(List visibleColumns, int firstVisibleRow, int QueryItemText(this, f + startRow, column, out var text, ref strOffsetX, ref strOffsetY); bool rePrep = false; + Color foreColor = _foreColor; + Font font = Font; currentCell.Column = column; currentCell.RowIndex = f + startRow; if (_selectedItems.Contains(currentCell)) { - _renderer.PrepDrawString(Font, SystemColors.HighlightText); + foreColor = SystemColors.HighlightText; rePrep = true; } + if (text.Length == 0 && mouseCell == currentCell) + { + font = new Font(Font, FontStyle.Regular); + foreColor = SystemColors.GrayText; + text = column.Text; + rePrep = true; + } + if (rePrep) + { + _renderer.PrepDrawString(font, foreColor); + } DrawString(text, new Rectangle(point.X + strOffsetX, point.Y + strOffsetY, column.Width, ColumnHeight)); diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs index bdf5df53d34..c7419ee8468 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs @@ -223,6 +223,13 @@ protected override void OnDoubleClick(EventArgs e) [DefaultValue(true)] public bool GridLines { get; set; } = true; + /// + /// Gets or sets a value indicating whether empty cells will display their column's text when the mouse cursor is placed over them + /// + [DefaultValue(false)] + [Category("Appearance")] + public bool ShowColumnTextOnHover { get; set; } + /// /// Gets or sets a value indicating whether the control is horizontal or vertical /// diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index 29df6f3fddd..0aeb6cc59f3 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -182,6 +182,7 @@ private InputRoll MakeInputRoll(int? insertAfter = null) InputPaintingMode = true, LetKeysModifySelection = true, Rotatable = true, + ShowColumnTextOnHover = true, // user configurable AlwaysScroll = Settings.FollowCursorAlwaysScroll, Font = Settings.TasViewFont, @@ -1276,13 +1277,9 @@ private void TasView_PointedCellChanged(object sender, InputRoll.CellEventArgs e InputRoll roll = (InputRoll)sender; toolTip1.SetToolTip(roll, null); - if (e.NewCell.RowIndex is null) - { - return; - } - - if (!MouseButtonHeld) + if (e.NewCell.RowIndex is null || !MouseButtonHeld) { + SetTasViewRowCount(); // redraw return; } From 25a054f6d171cfa0180fb0af9298f4832dcbd684 Mon Sep 17 00:00:00 2001 From: SuuperW Date: Fri, 19 Jun 2026 16:16:10 -0500 Subject: [PATCH 2/4] simplify how InputRoll updates pointed cell; make column text on hover update while following cursor --- .../CustomControls/InputRoll/InputRoll.cs | 64 ++++++------------- .../tools/TAStudio/TAStudio.ListView.cs | 8 +-- 2 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs index c7419ee8468..3ff1896516f 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs @@ -732,8 +732,6 @@ public int FirstVisibleRow _programmaticallyUpdatingScrollBarValues = false; } } - _programmaticallyChangingRow = false; - PointMouseToNewCell(); } } @@ -806,8 +804,6 @@ private int LastVisibleRow } while ((lastVisible - value < 0 || _lagFrames[VisibleRows - halfRow] < lastVisible - value) && FirstVisibleRow != 0); } - _programmaticallyChangingRow = false; - PointMouseToNewCell(); } } @@ -918,12 +914,8 @@ public void ScrollToIndex(int index) } } } - _programmaticallyChangingRow = false; - PointMouseToNewCell(); } - public bool _programmaticallyChangingRow = false; - /// /// Scrolls so that the given index is visible, if it isn't already; doesn't use scroll settings. /// @@ -931,8 +923,6 @@ public void MakeIndexVisible(int index) { if (!IsVisible(index)) { - _programmaticallyChangingRow = true; - if (FirstVisibleRow > index) { FirstVisibleRow = index; @@ -990,32 +980,16 @@ public IEnumerable GenerateContextMenuItems() private bool _columnDownMoved; private int _previousX; // TODO: move me - // It's necessary to call this anytime the control is programmatically scrolled - // Since the mouse may not be pointing to the same cell anymore - public void PointMouseToNewCell() + public bool SuppressCellChange; + + private void PointMouseToNewCell() { + if (SuppressCellChange) return; + if (_currentX.HasValue && _currentY.HasValue) { var newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - if (CurrentCell != newCell) - { - if (QueryFrameLag != null && newCell.RowIndex.HasValue) - { - newCell.RowIndex += CountLagFramesDisplay(newCell.RowIndex.Value); - } - - newCell.RowIndex += FirstVisibleRow; - if (newCell.RowIndex < 0) - { - newCell.RowIndex = 0; - } - - if (_programmaticallyChangingRow) - { - _programmaticallyChangingRow = false; - CellChanged(newCell); - } - } + CellChanged(newCell); } } @@ -1046,18 +1020,6 @@ protected override void OnMouseMove(MouseEventArgs e) Cell newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - // SuuperW: Hide lag frames - if (QueryFrameLag != null && newCell.RowIndex.HasValue) - { - newCell.RowIndex += CountLagFramesDisplay(newCell.RowIndex.Value); - } - - newCell.RowIndex += FirstVisibleRow; - if (newCell.RowIndex < 0) - { - newCell.RowIndex = 0; - } - if (!newCell.Equals(CurrentCell)) { CellChanged(newCell); @@ -1627,6 +1589,7 @@ private void VerticalBar_ValueChanged(object sender, EventArgs e) Refresh(); } + PointMouseToNewCell(); if (_horizontalOrientation) { ColumnScroll?.Invoke(this, e); @@ -1644,6 +1607,7 @@ private void HorizontalBar_ValueChanged(object sender, EventArgs e) Refresh(); } + PointMouseToNewCell(); if (_horizontalOrientation) { RowScroll?.Invoke(this, e); @@ -1901,6 +1865,18 @@ private Cell CalculatePointedCell(int x, int y) if (!(IsPaintDown || rightButton) && newCell.RowIndex <= -1) // -2 if we're entering from the top { newCell.RowIndex = null; + return newCell; + } + + if (QueryFrameLag != null) + { + newCell.RowIndex += CountLagFramesDisplay(newCell.RowIndex.Value); + } + + newCell.RowIndex += FirstVisibleRow; + if (newCell.RowIndex < 0) + { + newCell.RowIndex = 0; } return newCell; diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index 0aeb6cc59f3..1750491948d 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -763,10 +763,6 @@ private void TasView_MouseDown(object sender, MouseEventArgs e) UpdateActiveMovieInputs(); } - // only on mouse button down, check that the pointed to cell is the correct one (can be wrong due to scroll while playing) - roll._programmaticallyChangingRow = true; - roll.PointMouseToNewCell(); - if (e.Button == MouseButtons.Middle) { if (MainForm.EmulatorPaused) @@ -1342,7 +1338,9 @@ private void TasView_PointedCellChanged(object sender, InputRoll.CellEventArgs e if (MouseButtonHeld) { - roll.MakeIndexVisible(roll.CurrentCell.RowIndex.Value); // todo: limit scrolling speed + roll.SuppressCellChange = true; // avoid inifinite recursion of scrolling cuasing PointedCellChanged + roll.MakeIndexVisible(roll.CurrentCell.RowIndex.Value); + roll.SuppressCellChange = false; SetTasViewRowCount(); // refreshes } } From 2901970a714df6ff3125792a3c8d1edab30c3f9d Mon Sep 17 00:00:00 2001 From: SuuperW Date: Sat, 20 Jun 2026 13:32:28 -0500 Subject: [PATCH 3/4] make InputRoll handle its own ShowColumnTextOnHover redrawing on pointed cell change --- .../CustomControls/InputRoll/InputRoll.cs | 27 ++++++++----------- .../tools/TAStudio/TAStudio.ListView.cs | 1 - 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs index 3ff1896516f..6bdc9143515 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs @@ -1020,21 +1020,12 @@ protected override void OnMouseMove(MouseEventArgs e) Cell newCell = CalculatePointedCell(_currentX.Value, _currentY.Value); - if (!newCell.Equals(CurrentCell)) + bool changed = CellChanged(newCell); + if (changed && (ShowColumnTextOnHover || IsHoveringOnColumnCell || WasHoveringOnColumnCell)) { - CellChanged(newCell); - - if (IsHoveringOnColumnCell - || (WasHoveringOnColumnCell && !IsHoveringOnColumnCell)) - { - Refresh(); - } - else if (_columnDown != null) - { - Refresh(); - } + 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) { Refresh(); } @@ -1561,13 +1552,15 @@ private void OrientationChanged() /// /// Call this function to change the CurrentCell to newCell /// - private void CellChanged(Cell newCell) + /// true if CurrentCell was changed + private bool CellChanged(Cell newCell) { + if (newCell == CurrentCell) return false; + _lastCell = CurrentCell; CurrentCell = newCell; - if (PointedCellChanged is not null - && !(_lastCell?.Column == CurrentCell.Column && _lastCell?.RowIndex == CurrentCell.RowIndex)) //TODO isn't this just `Cell.==`? --yoshi + if (PointedCellChanged is not null) { PointedCellChanged(this, new CellEventArgs(_lastCell, CurrentCell)); } @@ -1580,6 +1573,8 @@ private void CellChanged(Cell newCell) { _hoverTimer.Stop(); } + + return true; } private void VerticalBar_ValueChanged(object sender, EventArgs e) diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index 1750491948d..279776d1efc 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -1275,7 +1275,6 @@ private void TasView_PointedCellChanged(object sender, InputRoll.CellEventArgs e if (e.NewCell.RowIndex is null || !MouseButtonHeld) { - SetTasViewRowCount(); // redraw return; } From 478952e115b335195b4a1a35edd8b17e199d8b4a Mon Sep 17 00:00:00 2001 From: SuuperW Date: Sat, 20 Jun 2026 13:39:49 -0500 Subject: [PATCH 4/4] do not show hover text when painting, dragging a cell, or when the mouse has left --- .../CustomControls/InputRoll/InputRoll.Drawing.cs | 6 +++++- .../CustomControls/InputRoll/InputRoll.cs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs index 716a3a0e210..d4db0955ada 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.Drawing.cs @@ -189,7 +189,11 @@ private void DrawData(List visibleColumns, int firstVisibleRow, int _renderer.PrepDrawString(Font, _foreColor); Cell currentCell = new(); - Cell mouseCell = ShowColumnTextOnHover ? CurrentCell : null; + Cell mouseCell = null; + if (ShowColumnTextOnHover && _draggingCell == null && !IsPaintDown) + { + mouseCell = CurrentCell; + } if (HorizontalOrientation) { for (int j = 0; j < visibleColumns.Count; j++) diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs index 6bdc9143515..91dfb5bc4a9 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs @@ -1057,7 +1057,7 @@ protected override void OnMouseLeave(EventArgs e) bool refresh = false; _currentX = null; _currentY = null; - if (IsHoveringOnColumnCell) + if (IsHoveringOnColumnCell || ShowColumnTextOnHover) { refresh = true; }