Skip to content

Fixes #4963, #5064. FileDialog nav fixes & TableView redesign#5062

Merged
tig merged 39 commits intodevelopfrom
Issue-4963-filedialog
Apr 26, 2026
Merged

Fixes #4963, #5064. FileDialog nav fixes & TableView redesign#5062
tig merged 39 commits intodevelopfrom
Issue-4963-filedialog

Conversation

@tig
Copy link
Copy Markdown
Collaborator

@tig tig commented Apr 22, 2026

Summary

FileDialog Fixes

  • Fixed keyboard navigation issues in FileDialog
  • Fixed TableView activation to use OnActivating pattern
  • Fixed TableView key handling

TableView Redesign (Breaking Changes)

Type consolidation & IValue support:

  • Consolidated \SelectedCellChangedEventArgs\ into immutable \TableSelection\ / \TableSelectionRegion\ types
  • Implemented \IValue<TableSelection?>\ on \TableView\
  • \TableSelectionRegion\ properties are init-only for \GetHashCode\ safety

Terminology — \Selection\ → \Cursor\ for navigation APIs:

  • \ChangeSelectionByOffset\ → \MoveCursorByOffset\
  • \ChangeSelectionToEndOfRow\ → \MoveCursorToEndOfRow\
  • \ChangeSelectionToStartOfRow\ → \MoveCursorToStartOfRow\
  • \ChangeSelectionToEndOfTable\ → \MoveCursorToEndOfTable\
  • \ChangeSelectionToStartOfTable\ → \MoveCursorToStartOfTable\
  • Backing fields: _selectedColumn/_selectedRow\ → _cursorColumn/_cursorRow\
  • All XML docs updated: \selected cell\/\�ctive cell\ → \cursor cell\

Return type cleanup:

  • All cursor-movement and selection methods return \�ool\ (true = success, false = null table guard)
  • All \AddCommand\ lambdas collapsed to single-line expressions

Partial class extraction:

  • Created \TableView.Content.cs\ for all content/viewport-related members (\ColumnOffset, \RowOffset, \CalculateContentSize, \MaxViewPort, \EnsureValidScrollOffsets, \UseAllRowsForContentCalculation, \RefreshContentSize, \OnViewportChanged)

Bug fixes:

  • Fixed \ToggleExtendKeyboard\ — all three branches had inverted logic (toggle-off was a no-op, dead code in else branch)
  • Fixed \GetAllSelectedCells: incorrect \Count == 0\ → \Count > 0\

XML docs & documentation:

  • Full pass on XML docs for all TableView types
  • Rewrote \docfx/docs/tableview.md\ as complete deep-dive

Known Issue

  • Ctrl+Click adds to a selection region but does not remove (toggle off) — regression to be fixed separately

Remaining (future PR)

  • Legacy API removal: \CursorChanged, \SelectedColumn/\SelectedRow\ properties, \CellActivated, \CellToggled, \TableViewSelectionSnapshot\

tig added 5 commits April 21, 2026 09:23
Fixes text input controls to ignore Alt/Ctrl-modified keys, even with AssociatedText (Kitty protocol). Updates FileDialog TableView height. Adds regression tests for input handling and hotkey routing. Documents FileDialog keyboard/nav issues. Refactors KeyboardEventTests for clarity.
Improve FileDialog navigation and TableView key handling

- Reset TableView viewport X and Y to 0 on navigation for consistent top-left alignment in FileDialog.
- Enable TabStop on _tableViewContainer for better keyboard accessibility.
- Adjust _tableView height and anchor _tbFind Y position for improved layout robustness.
- Refactor TableView key handling: ignore control/modified keys, handle navigation only when focused and rows exist, and return true when a key is handled.
tig added 3 commits April 23, 2026 07:33
Replaces OnActivated with OnActivating, updating the method to return a bool based on ToggleCurrentCellSelection. This supports cancellable or conditional activation in line with new event handling conventions.
tig added 11 commits April 23, 2026 15:57
Refactor TableView to v2 command/event architecture

- Implements IValue<Point?> and standard ValueChanged events
- Replaces OnMouseEvent with MouseBindings for all mouse actions
- Aligns Command.Accept/Activate/Toggle semantics to v2 standards
- Adds DefaultKeyBindings (Emacs, Home/End, Space, etc.)
- Uses C# 14 semi-auto properties for selection, default -1
- Moves collection-navigator logic to OnKeyDownNotHandled
- Threads ICommandContext through selection/navigation methods
- Marks legacy events/types as [Obsolete] with shims for compat
- Updates FileDialog and DatePicker to new TableView API
- Adds/updates tests and documents changes in tableview-refactor-summary.md
- Cleans up code style and removes dead code throughout
Comprehensive tests for TableView navigation, selection, events, and edge cases. Ensures current behavior is preserved ahead of planned redesign.
Refactored TableView to use TableSelection/TableSelectionRegion for richer selection state, replacing Point-based selection. Renamed EnsureSelectedCellIsVisible to EnsureCursorIsVisible and updated all references. Changed Command.Toggle to Command.ToggleExtend for extended selection. Improved null handling for Table and selection state, preventing NullReferenceExceptions. Updated tests and documentation to match the new model. Made minor code style and naming improvements.
Replaced all usages of SelectedRow/SelectedColumn with the new Value property and its Cursor.X/Y members for improved selection state management and null-safety. Updated event handlers to use ValueChanged instead of SelectedCellChanged, and replaced direct selection assignments with SetSelection calls. Modernized UI control initialization, streamlined menu/status bar construction, and improved code style and null handling throughout. Marked SelectedCellChanged as obsolete and updated tests and scenarios to use the new selection APIs.
No code modifications were present in the provided diff. No commit necessary.
Renamed the TableView event and event args from SelectedCellChanged/SelectedCellChangedEventArgs to CursorChanged/CursorChangedEventArgs. Updated all references, event invocations, and tests accordingly. Improved comments to clarify the event tracks cursor position changes, not cell selection.
Major overhaul of TableView selection and event model:
- Remove obsolete events (CellActivated, CellToggled, CursorChanged) and related args.
- All selection state now managed via Value (TableSelection).
- Internal selection fields are private; use SetSelection/Value APIs.
- Update all code/tests to use Value.Cursor and ValueChanged.
- Accept/Accepted replaces CellActivated; ToggleExtend handled directly.
- Deep-copy multi-selection regions for immutability.
- Refactor navigation, selection, and rendering to new model.
- Update all scenarios and tests for new APIs.
- Modernize code style and remove redundant code.
Improved and expanded XML documentation and in-code comments for TableView and related sources, fixing typos and grammar for accuracy and consistency. Major updates to tableview.md add a detailed table of contents, expanded sections, code examples, and event usage. Minor code fixes and improved parameter tags enhance maintainability and developer experience.
Refactored TableView.Selection.cs to move IValue<TableSelection?> implementation to the end of the file and organize related properties. Changed TableSelectionRegion to use init-only properties for immutability. Updated selection region logic to use immutable instances, improved region clamping, and fixed minor logic issues. Enhanced code style and maintainability without altering selection behavior.
Refactor TableView internals and API to use "cursor" instead of "selected"/"selection" for navigation state. Update all related fields, methods, comments, and tests for clarity and consistency. No functional changes; improves code readability and aligns with TableSelection.Cursor semantics.
Reorganize TableView by moving content-related properties and methods (content size, scrolling, viewport management) into TableView.Content.cs. This structural refactor improves code organization, separation of concerns, and maintainability. No functional changes introduced.
@tig tig changed the title Fixes #4963 - File Dialog nav issues Fixes #4963, #5064. FileDialog nav fixes & TableView redesign Apr 24, 2026
tig added 3 commits April 24, 2026 15:50
Comprehensive TableView API overhaul for v2.0.0: unified selection types, IValue<TableSelection?> support, navigation API terminology shift from "Selection" to "Cursor", and legacy API deprecation. Fixes keyboard selection toggling and region calculation bugs. Extracts content/viewport logic to a partial class and updates XML/docs. Ctrl+Click toggle regression noted for follow-up.
@tig
Copy link
Copy Markdown
Collaborator Author

tig commented Apr 24, 2026

I'm currently working on two last issues:

  • TableView - Ctrl-Click extends selection to include the clicked cell but it does not do the opposite - FIXED
  • FileDialog - Still resizes crazily.

@tig tig requested review from YourRobotOverlord and Copilot and removed request for Copilot April 24, 2026 21:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Terminal.Gui’s FileDialog and TableView to align with the v2 command/value patterns, fixing reported navigation issues and introducing a breaking TableView selection/cursor API redesign with updated docs and extensive regression/baseline tests.

Changes:

  • FileDialog: keyboard/navigation fixes, cancel/result handling updates, and (gated) tree-view work.
  • TableView: redesign around IValue<TableSelection?>, cursor-based navigation APIs, selection region types, and refactoring into partial files.
  • Input pipeline + docs/tests: Kitty/ANSI key parsing adjustments, TableView deep-dive rewrite, and new/updated regression tests.

Reviewed changes

Copilot reviewed 65 out of 65 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
docfx/docs/tableview.md Rewritten TableView deep-dive documenting new selection/cursor/value model and usage.
Tests/UnitTestsParallelizable/Views/TextViewTests.cs Adds regression tests for Alt/Ctrl + AssociatedText not inserting text.
Tests/UnitTestsParallelizable/Views/TextValidateFieldTests.cs Adds regression tests for Alt/Ctrl + AssociatedText not inserting text.
Tests/UnitTestsParallelizable/Views/TextFieldTests.cs Adds regression tests for Alt/Ctrl + AssociatedText not inserting text.
Tests/UnitTestsParallelizable/Views/TableViewTests.cs Updates tests to new cursor/Value API and adds ToggleExtend/Accepted coverage.
Tests/UnitTestsParallelizable/Views/TableViewLegacyTests.cs Updates legacy-facing tests to new selection types and ValueChanged event.
Tests/UnitTestsParallelizable/Views/TableViewBaselineTests.cs New baseline suite to lock in TableView behavior during redesign.
Tests/UnitTestsParallelizable/Views/LabelTests.cs Adjusts hotkey test expectations/flow.
Tests/UnitTestsParallelizable/Views/HexViewTests.cs Adds regression tests preventing ctrl/alt-modified edits.
Tests/UnitTestsParallelizable/Views/ButtonTests.cs Updates test comment to match HotKey behavior.
Tests/UnitTestsParallelizable/ViewBase/ViewCommandTests.cs Adds baseline test that HotKey command returns true.
Tests/UnitTestsParallelizable/ViewBase/Keyboard/KeyboardEventTests.cs Adds routing regression test and refactors some setup/formatting.
Tests/IntegrationTests/FluentTests/FileDialogTests.cs Gates tree-related integration tests behind compile symbol.
Terminal.sln.DotSettings Adds a word to ReSharper user dictionary.
Terminal.Gui/Views/TreeView/TreeView.Navigation.cs Adds (gated) prototype ExpandParents implementation.
Terminal.Gui/Views/TextInput/TextView/TextView.Keyboard.cs Prevents Alt/Ctrl modified keys from being inserted as text.
Terminal.Gui/Views/TextInput/TextValidateField.cs Prevents Alt/Ctrl modified keys from being inserted as text.
Terminal.Gui/Views/TextInput/TextField/TextField.Keyboard.cs Prevents Alt/Ctrl modified keys from being inserted as text.
Terminal.Gui/Views/TableView/TreeTableSource.cs Updates TreeTableSource to use cursor (Value.Cursor) instead of SelectedRow/SelectedColumn.
Terminal.Gui/Views/TableView/TableView.Navigation.cs Refactors navigation methods to cursor terminology and return values.
Terminal.Gui/Views/TableView/TableView.Mouse.cs Removes legacy OnMouseEvent implementation (migrated to bindings/commands).
Terminal.Gui/Views/TableView/TableView.Drawing.cs Refactors/extends rendering helpers (headers, width calc, truncation/padding).
Terminal.Gui/Views/TableView/TableView.Content.cs Extracts viewport/content/offset logic into new partial file.
Terminal.Gui/Views/TableView/TableView.CellMapping.cs Minor doc cleanup.
Terminal.Gui/Views/TableView/TableStyle.cs Doc fixes/clarifications.
Terminal.Gui/Views/TableView/TableSelectionRegion.cs New immutable-ish selection region type with equality/hash.
Terminal.Gui/Views/TableView/TableSelection.cs New TableSelection snapshot type (cursor + regions) with equality/hash.
Terminal.Gui/Views/TableView/SelectedCellChangedEventArgs.cs Removes legacy SelectedCellChanged args type.
Terminal.Gui/Views/TableView/ListTableSource.cs Fixes cached min-width tracking and improves docs.
Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs Updates checkbox wrapper to use ToggleExtend + key interception.
Terminal.Gui/Views/TableView/CellToggledEventArgs.cs Removes legacy CellToggled args type.
Terminal.Gui/Views/TableView/CellActivatedEventArgs.cs Removes legacy CellActivated args type.
Terminal.Gui/Views/HexView.cs Prevents Ctrl-modified keys from editing hex data.
Terminal.Gui/Views/FileDialogs/SaveDialog.cs Updates cancel detection + nullability and constructor style.
Terminal.Gui/Views/FileDialogs/OpenDialog.cs Updates cancel detection for FilePaths.
Terminal.Gui/Views/FileDialogs/FileDialogStyle.cs Makes style members nullable when tree is disabled; gates tree properties.
Terminal.Gui/Views/FileDialogs/FileDialogCollectionNavigator.cs Updates to cursor-based column selection and null-safe conversion.
Terminal.Gui/Views/FileDialogs/FileDialog.cs Refactors dialog layout, adds CancelButton, updates TableView wiring/events.
Terminal.Gui/Views/FileDialogs/FileDialog.TableView.cs Updates handlers to Accepted/ValueChanged and cursor-based row access.
Terminal.Gui/Views/FileDialogs/FileDialog.Navigation.cs Updates restore selection and scroll resets; gates tree visibility logic.
Terminal.Gui/Views/FileDialogs/FileDialog.Commands.cs Updates selection guards to Value-based model.
Terminal.Gui/Views/DialogTResult.cs Simplifies viewport change content-size calculation.
Terminal.Gui/Views/Dialog.cs Adjusts Result setter bounds check and result-setting behavior.
Terminal.Gui/Views/DatePicker.cs Migrates calendar interactions to Activated/Accepted + cursor-based access.
Terminal.Gui/Views/CollectionNavigation/TableCollectionNavigator.cs Updates to cursor-based column selection and adds stricter null handling.
Terminal.Gui/ViewBase/View.Command.cs Adds inline questions/comments about HotKey handling return value.
Terminal.Gui/Input/Command.cs Updates ToggleExtend docstring.
Terminal.Gui/FileServices/FileSystemTreeBuilder.cs Adds reparse-point guards to avoid traversal cycles; makes IncludeFiles settable.
Terminal.Gui/Drivers/AnsiHandling/Ss3Pattern.cs Minor Regex instantiation/style refactor.
Terminal.Gui/Drivers/AnsiHandling/KittyKeyboardPattern.cs Refactors parsing locals and ensures Key instances aren’t shared.
Terminal.Gui/Drivers/AnsiHandling/EscAsAltPattern.cs Minor constructor style refactor.
Terminal.Gui/Drivers/AnsiHandling/CsiKeyPattern.cs Ensures new Key instances returned + asserts around Handled sharing.
Terminal.Gui/Drivers/AnsiHandling/CsiCursorPattern.cs Ensures new Key instances returned + asserts around Handled sharing.
Terminal.Gui/Drivers/AnsiHandling/AnsiKeyboardParserPattern.cs Changes GetKey to clone returned Key (but currently lacks null guard).
Examples/UICatalog/UICatalogRunnable.cs Updates scenario list selection APIs to cursor/value model.
Examples/UICatalog/Scenarios/TableViewTest.cs Updates scenario to cursor/value APIs and formatting cleanup.
Examples/UICatalog/Scenarios/TableEditor.cs Updates to Accepted/ValueChanged and cursor/value APIs.
Examples/UICatalog/Scenarios/MultiColouredTable.cs Updates to Accepted and cursor/value APIs; refactors edit flow.
Examples/UICatalog/Scenarios/MinimalSpinnerDemo.cs Improves demo UI + hotkeys and toggles for spinner properties.
Examples/UICatalog/Scenarios/ListColumns.cs Updates to ValueChanged cursor reporting and formatting cleanup.
Examples/UICatalog/Scenarios/FileDialogExamples.cs Updates TableStyle nullability usage; adds default Path; gates tree code (symbol mismatch noted).
Examples/UICatalog/Scenarios/CsvEditor.cs Updates to Accepted/ValueChanged and cursor/value APIs; refactors prompts/guards.
Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs Updates selection handling to cursor/value APIs and improves null guards.

Comment thread Tests/UnitTestsParallelizable/Views/TableViewBaselineTests.cs
Comment thread Terminal.Gui/Views/FileDialogs/FileDialogStyle.cs Outdated
Comment thread Terminal.Gui/ViewBase/View.Command.cs
Comment thread Terminal.Gui/Drivers/AnsiHandling/AnsiKeyboardParserPattern.cs
Comment thread Terminal.Gui/Views/Dialog.cs Outdated
Comment thread Examples/UICatalog/Scenarios/FileDialogExamples.cs Outdated
Comment thread Terminal.Gui/Views/TableView/TableView.Drawing.cs
Comment thread Terminal.Gui/Views/TableView/TableView.Content.cs
Comment thread Terminal.Gui/Views/CollectionNavigation/TableCollectionNavigator.cs
Comment thread Terminal.Gui/Views/FileDialogs/FileDialog.cs
tig and others added 3 commits April 25, 2026 11:19
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@tznind
Copy link
Copy Markdown
Collaborator

tznind commented Apr 25, 2026

expand from this node all the way to its root".

Is that the right general direction of one did want to have a dir tree track a changing path?

TreeView operates on delegates for sub-branch discovery. This is very important for performancd as it allows us to only enumerate exposed nodes' children.

So to reveal a file it would be best to use the DirectoryInfo root of a FileInfo and say:

  • expand c:
  • expand temp
  • expand mydir

I.e. use the domain knowledge of file system rather than try to implement a generic node discovery system - which goes against design philosophy.

Copilot AI and others added 2 commits April 26, 2026 14:19
Copilot AI and others added 2 commits April 26, 2026 14:25
Copilot finished work on behalf of tig April 26, 2026 14:28
tig added 4 commits April 26, 2026 08:41
FileDialog TreeView feature is now disabled via `#if !FILEDIALOG_ENABLE_TREE`, hiding all related UI and logic. TreeView initialization and toggle button are only present when the feature is off. `FileDialogStyle` now supports a nullable file system and defaults `DefaultUseColors` to true. FileDialog-related config settings are removed. `TableView.TruncateOrPad` now truncates by grapheme cluster, preventing surrogate pair corruption. Adds a test to ensure truncation does not throw or produce invalid surrogates with emoji.
Removes FILEDIALOG_ENABLE_TREE conditional blocks, making the directory tree, toggle button, and related styles always active in FileDialog. Updates FileDialogStyle and tests to support the unified implementation. FileDialogExamples now sets PreserveFilenameOnDirectoryChanges via checkbox. Tree functionality is now a standard, always-on part of the dialog UI.
- Add ".lnk" color mapping to FileSystemColorProvider
- Refine FileDialog pane border and alignment
- Reorder _treeView initialization for clarity
- Simplify TableView style for a cleaner appearance
- Use theme-based colors in TableView for consistency
- Ensure column color getter and style order are correct
- Set AllowsMultipleSelection to false in FileDialog
- Refactor ColumnStyle.Visible to use auto-property and MaxWidth logic
@tig tig merged commit 3dbaceb into develop Apr 26, 2026
11 checks passed
@tig tig deleted the Issue-4963-filedialog branch April 26, 2026 15:47
@tznind
Copy link
Copy Markdown
Collaborator

tznind commented Apr 27, 2026

File dialog in designer is now putting CPU to 100% just clicking around in TableView.

This happens in all 3 of these versions:

2.0.0-rc.5
2.0.1-develop.1
2.0.0-develop.5376

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

5 participants