Add Terminal theme that inherits the terminal's ANSI colour scheme#176
Conversation
|
Code Review Overview This PR adds a TerminalTheme that restricts color output to the 16 named ANSI colors, letting the terminal apply its own configured palette. AppTheme gains a UseTerminalColors flag, ThemeManager propagates it to Application.Force16Colors, the theme toggle cycles generically through N themes instead of hardcoding 2, and tests/docs are updated. The approach is sound. Potential Issues 1. Driver propagation is coupled to an implementation detail The comment in ThemeManager.cs acknowledges this workaround for the v2 facade driver caching its own flag. If Terminal.Gui v2 fixes this in a future release, the propagation will silently double-set the flag (harmless) or — if the property is removed — break compilation. Worth adding a version-pinned comment so it is clear when this can be removed. 2. TerminalTheme sets 3. Test covers
4. Global static mutation and parallel tests The new test sets Minor / Nits Misleading comment in TerminalTheme.cs: The comment says "All colors use the exact RGB values Terminal.Gui maps to the 16 ANSI color indices" — but the colors are constructed with Assert.All: ScopeView signal colors: The five oscilloscope signal colors (Green, Cyan, Yellow, Magenta, White) are hardcoded in ScopeView outside the theme system. They will be quantised to nearest ANSI equivalents automatically — probably fine, but worth a quick manual check of scope rendering under the Terminal theme to confirm traces remain readable. What Is Working Well
Summary Solid, well-structured addition. The two items most worth addressing before merge are the |
Adds a third built-in theme that renders using the terminal's own 16-color ANSI palette instead of fixed 24-bit RGB values: - TerminalTheme defines all colors with the exact ColorName16 values so they map onto ANSI palette indices without approximation - AppTheme gains a UseTerminalColors flag; ThemeManager.SetTheme toggles Application.Force16Colors (and the active driver) accordingly, so the driver emits standard SGR 30-37/90-97 codes that the terminal renders with its configured colour scheme - View menu theme toggle now cycles Dark -> Light -> Terminal https://claude.ai/code/session_01PH2h6mTwUqKqdx5dZEceCi
65e7f0b to
2df3088
Compare
|
Code Review: Add Terminal theme that inherits the terminal's ANSI colour scheme
Overview This PR adds a third built-in theme ( Strengths
Issues and Suggestions Minor: Static state in Force16Colors test risks flakiness under parallel execution The Minor: ColorScheme attributes not covered by the round-trip test
Observation: Scope view signal colors
Nit: Test cleanup uses a different API than the rest of the test The Summary
Clean, well-tested feature addition. The one follow-up worth checking: whether |
…yer 1) (#165) * Upgrade Terminal.Gui 2.0.0 -> 2.4.5 (full UI-layer migration) The component-test APIs (Application.Create, InjectKey/InjectSequence, VirtualTimeProvider) first appear in Terminal.Gui 2.1.0, which also landed a breaking API redesign. This ports the whole UI layer to 2.4.5: - Namespace reorg: add GlobalUsings for Terminal.Gui.{App,ViewBase,Views, Drawing,Input,Drivers,Text,Configuration}; alias Attribute -> Drawing.Attribute. - ColorScheme -> Scheme; view.ColorScheme = x -> view.SetScheme(x); add a WithScheme() fluent helper for initializer-style scheme assignment. - Toplevel -> Window; RadioGroup -> OptionSelector (Labels/Value/ValueChanged). - TableView: SelectedRow -> Value?.SelectedCell.Y; SelectedCellChanged -> ValueChanged<TableSelection>; MouseClick -> MouseEvent(Mouse). - TreeView ObjectActivated -> Activated (read SelectedObject). - ListView OpenSelectedItem -> Accepting; drop TopItem (SelectedItem autoscrolls). - MenuItem shortcutKey: named arg -> positional Key. - Custom drawing: Driver!.X(...) -> view-level SetAttribute/AddRune/AddStr/Move in OnDrawingContent(DrawContext). - Application.Top -> TopRunnable/TopRunnableView; SizeChanging -> SubViewLayout; Colors.ColorSchemes["Menu"] -> SchemeManager.AddScheme; MessageBox.* now take Application.Instance; ShadowStyle.None -> ShadowStyles.None; Subviews -> SubViews; TextField.CursorPosition -> MoveEnd(). Known regression (flagged for review): Terminal.Gui 2.4 adornments have no independent Scheme, so per-border colouring (grey borders, focus-highlight title) now inherits the view scheme; focus highlight reapplied via FrameView scheme. Builds clean; all 613 existing tests pass; published --help smoke exits 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add layer-1 in-process TUI component tests Constructs the real Terminal.Gui views/dialogs and asserts on observable component behaviour: - MonitoredVariablesView: AddVariable/RemoveVariable, scope-selection bookkeeping, per-client-handle idempotency. - ConnectDialog: endpoint protocol-prefix handling, publishing interval, and the authentication selector (migrated RadioGroup -> OptionSelector). - Theme/Scheme: DarkTheme/LightTheme schemes and ThemeStyler.ApplyTo guard the ColorScheme -> Scheme migration. Tests run in a non-parallel xUnit collection because Terminal.Gui's Application is global state. Picked up automatically by `dotnet test` / CI. Rendered cell-buffer assertions are intentionally deferred to the black-box PTY suite: Terminal.Gui 2.4.5 stable exposes no public headless driver (Application.Create leaves Driver null; DriverAssert is develop-only). Documented in docs/TESTING.md. 627/627 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Fix behavioral regressions found by migration review Adversarial review of the Terminal.Gui 2.0->2.4 migration confirmed three event-routing / API-semantics regressions (TG 2.4 moved selection/activation from overridden handlers into the command pipeline, which now runs AFTER the raw MouseEvent/Accepting events): - MonitoredVariablesView.HandleMouseClick: dropped `e.Handled = true` on Sel-column clicks. Marking it handled now pre-empts TableView's LeftButtonClicked -> Command.Activate -> SetSelection, so a Sel click toggled scope but no longer highlighted the row or raised SelectedVariableChanged. Unhandled restores both. - SaveRecordingDialog.OnFileListOpenSelected: set `e.Handled = true`. An unhandled Accepting bubbles Accept to the default Save button, so navigating a folder or picking a file would save+close the dialog mid-browse. - SaveRecordingDialog.NavigateToSelected: null-safe guard. ListView.SelectedItem is now int? (null = none); the OR-form guard didn't catch null and dereferenced null.Value (InvalidOperationException at a CSV-less filesystem root). - LogView: restore log auto-scroll via EnsureSelectedItemVisible() (TG 2.4 removed ListView.TopItem); without it the log stopped following new entries. 627/627 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Migrate Terminal theme and tests added on main to Terminal.Gui 2.4.5 Rebasing onto main brought in the Terminal theme (#176) and its tests, which were written against Terminal.Gui 2.0: - TerminalTheme: ColorScheme -> Scheme; drop the local Attribute alias now provided by GlobalUsings. - ThemeManager: Application.Force16Colors no longer exists as a static; set the flag on Application.Driver only. - ThemeManagerTests: assert UseTerminalColors on the theme since the driver (which now owns Force16Colors) is null in headless tests. - ThemeSchemeTests: ThemeStyler.ApplyTo was dropped in favour of main's leaner surface (#177); test ApplyToFrame instead. * Address review feedback: null-safety, readability, and test coverage - ScopeDialog: replace GetScheme()! with an explicit fallback to the theme's main scheme, removing the NRE risk reviewers flagged. - ConnectDialog: normalize an empty password box to null so Password honours its nullable contract; downstream sends the same bytes. - Expand the collapsed single-line Scheme initializers in HelpDialog, WriteValueDialog and MonitoredVariablesView to the multi-line style used elsewhere. - AppTheme: mark the now-unapplied HighlightTitleBorderColorScheme with a TODO tied to the planned VisualRoles work. - AddressSpaceView: document why reading SelectedObject in Activated is race-free. - Tests: cover TerminalTheme in ThemeSchemeTests, add a WithScheme unit test, assert Password stays null without input, and dispose views in TUI tests to stop ThemeChanged handler leaks across the collection. - docs/TESTING.md: note the E2E project ships in the follow-up PR. * Address follow-up review: obsolete dead scheme, typed-password test, polish - AppTheme: mark HighlightTitleBorderColorScheme [Obsolete] so future callers can't silently rely on a scheme that is never applied. - ConnectDialogTests: cover the non-null path of the Password getter by typing into the dialog's Secret TextField. - MonitoredVariablesView: note that Mouse.Position is Point? in Terminal.Gui 2.4 so the null pattern isn't stripped as redundant. - NodeDetailsView: use WithScheme for the copy button like every other initializer in the migration. - ScopeView: drop a stray blank line left by the Driver-null-check removal. * Add TUI screenshots verifying the Terminal.Gui 2.4.5 migration Captured against the in-repo OPC UA test server (tmux + ANSI render): main window in all three themes, the migrated Connect dialog (OptionSelector), and the braille scope with four live signals. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a third built-in theme that renders using the terminal's own
16-color ANSI palette instead of fixed 24-bit RGB values:
they map onto ANSI palette indices without approximation
Application.Force16Colors (and the active driver) accordingly, so the
driver emits standard SGR 30-37/90-97 codes that the terminal renders
with its configured colour scheme
https://claude.ai/code/session_01PH2h6mTwUqKqdx5dZEceCi