|
1 | | -# ConsoleEx Roadmap |
| 1 | +# Roadmap |
2 | 2 |
|
3 | | -Findings from an honest architectural review of the framework. Organized by priority — foundations first, then polish, then growth. |
| 3 | +SharpConsoleUI is actively maintained and driven by real-world usage in production apps ([ServerHub](https://github.com/nickprotop/ServerHub), [LazyNuGet](https://github.com/nickprotop/lazynuget), [LazyDotIDE](https://github.com/nickprotop/lazydotide)). |
4 | 4 |
|
5 | | ---- |
6 | | - |
7 | | -## 1. API Consistency (High Priority) |
8 | | - |
9 | | -These are the things that will burn every new user on day one. |
10 | | - |
11 | | -### ~~Color Parameter Ordering~~ (Done) |
12 | | - |
13 | | -All `WithColors`, `WithFocusedColors`, and `WithHighlightColors` methods now consistently use `(foreground, background)` parameter ordering across all builders: ListBuilder, ButtonBuilder, WindowBuilder, and SpectreRenderableBuilder. |
14 | | - |
15 | | -### Method Naming |
16 | | - |
17 | | -Audit all builders for naming consistency: |
18 | | -- `WithHighlightColors` vs `WithFocusedColors` — are these the same concept with different names on different controls, or genuinely different states? If different, document the distinction clearly. If same, unify. |
19 | | -- `SimpleMode()` vs `With*()` prefix pattern — most methods use `With` prefix, some don't. Decide on one convention. |
20 | | - |
21 | | ---- |
22 | | - |
23 | | -## 2. Class Decomposition (High Priority) |
24 | | - |
25 | | -These files are too large and carry too many responsibilities. They'll slow down every future change. |
26 | | - |
27 | | -### Window.cs (2,350 lines) |
28 | | - |
29 | | -Currently acts as: control container, render coordinator, input dispatcher, state manager, lifecycle owner, scroll manager, and border owner. |
30 | | - |
31 | | -Split candidates: |
32 | | -- `WindowState` — state properties (position, size, minimized/maximized, title) |
33 | | -- `WindowControls` — child control management (add, remove, find by name) |
34 | | -- `WindowScrolling` — scroll offset, scroll-into-view logic |
35 | | -- Keep `Window` as the facade that delegates to these |
36 | | - |
37 | | -### WindowStateService.cs (43KB) |
38 | | - |
39 | | -This is the largest single file. Likely managing window creation, destruction, activation, Z-order, enumeration, and events all in one place. |
40 | | - |
41 | | -### AnsiConsoleHelper.cs (35KB) |
| 5 | +## Recently Shipped |
42 | 6 |
|
43 | | -A static helper with 1,000+ lines doing markup conversion, ANSI generation, string measurement, color parsing, and capture console creation. Split by concern: |
44 | | -- `MarkupConverter` — Spectre markup to ANSI |
45 | | -- `AnsiStringUtils` — substring, truncate, measure with ANSI awareness |
46 | | -- `CaptureConsoleFactory` — Spectre capture console creation |
| 7 | +- MVVM data binding — `INotifyPropertyChanged` on all controls, `Bind()` / `BindTwoWay()` API |
| 8 | +- CanvasControl — retained and immediate mode drawing with full graphics API |
| 9 | +- ImageControl — load and display PNG/JPEG/BMP/GIF/WebP/TIFF files in the terminal |
| 10 | +- TableControl DataGrid — virtual data source, sorting, filtering, inline editing, compound filter expressions |
| 11 | +- Gradient text and backgrounds with animation framework |
| 12 | +- Project templates — `dotnet new tui-app`, `tui-dashboard`, `tui-multiwindow` |
| 13 | +- .NET 8.0 + 9.0 multi-targeting |
| 14 | +- SourceLink and symbol packages for debugging |
| 15 | +- Compositor effects — PreBufferPaint/PostBufferPaint hooks for custom rendering |
47 | 16 |
|
48 | | -### NetConsoleDriver.cs (35KB) |
| 17 | +## Next |
49 | 18 |
|
50 | | -Input polling, mouse parsing, resize detection, ANSI output, cursor management, platform detection. Split input handling from output handling at minimum. |
| 19 | +- **DatePicker** — calendar-based date selection control |
| 20 | +- **TimePicker** — time selection with hour/minute/second |
| 21 | +- **Slider / RangeControl** — horizontal and vertical value sliders |
| 22 | +- **StatusBarControl** — per-window status bar (distinct from the system-level status bars) |
| 23 | +- **Instant input response** — replace polling-based input loop with event-driven wake for zero-latency keypress handling |
51 | 24 |
|
52 | | ---- |
53 | | - |
54 | | -## 3. Control Authoring Story (High Priority) |
55 | | - |
56 | | -This is the ceiling on adoption. Right now, writing a custom control means implementing 3-5 interfaces from scratch with no guidance on which combinations to use. |
57 | | - |
58 | | -### Add ControlBase Abstract Class |
59 | | - |
60 | | -``` |
61 | | -ControlBase : IWindowControl, IDOMPaintable, IDisposable |
62 | | - - Default implementations for layout properties, margins, visibility |
63 | | - - Default Invalidate() that walks up to container |
64 | | - - Abstract MeasureDOM() and PaintDOM() — the only things authors MUST implement |
| 25 | +## Later |
65 | 26 |
|
66 | | -InteractiveControlBase : ControlBase, IInteractiveControl, IFocusableControl |
67 | | - - Default focus management (HasFocus, IsEnabled, GotFocus/LostFocus events) |
68 | | - - Abstract ProcessKey() — the only thing authors MUST implement |
| 27 | +- ListControl data virtualization — virtual data source for 100K+ item lists |
| 28 | +- RadioButtonGroup — exclusive selection from a set |
| 29 | +- NumericSpinner — increment/decrement with arrow keys |
| 30 | +- ColorPicker — color selection dialog |
| 31 | +- Accordion / CollapsiblePanel |
| 32 | +- Custom control authoring SDK — `ControlBase` abstract class and guide for third-party control development |
69 | 33 |
|
70 | | -MouseAwareControlBase : InteractiveControlBase, IMouseAwareControl |
71 | | - - Default mouse event plumbing |
72 | | - - Virtual ProcessMouseEvent() with default no-op |
73 | | -``` |
| 34 | +## Future |
74 | 35 |
|
75 | | -This doesn't break existing controls — they can keep their direct interface implementations. But new control authors get a fast path. |
| 36 | +- **Web terminal backend** — run your TUI in a browser via WebSocket |
| 37 | +- **SSH remote session driver** — dedicated driver for remote sessions |
| 38 | +- **Plugin ecosystem** — community-contributed controls and themes |
76 | 39 |
|
77 | 40 | --- |
78 | 41 |
|
79 | | -## 4. Rendering Pipeline Optimization (Medium Priority) |
80 | | - |
81 | | -### String-to-Cell Round-Trip |
82 | | - |
83 | | -Current flow: Spectre Markup -> ANSI string -> parse to cells -> CharacterBuffer -> diff -> emit as ANSI string again. |
84 | | - |
85 | | -The markup-to-ANSI-to-cell-to-ANSI round-trip creates allocation pressure. Consider: |
86 | | -- Caching parsed cell arrays for static content (markup that doesn't change between frames) |
87 | | -- Direct cell emission from controls that don't use Spectre markup (buttons, rules, separators can write cells directly without going through string intermediary) |
88 | | - |
89 | | -### Two Buffer Systems |
90 | | - |
91 | | -`CharacterBuffer` (layout-level, per-window) and `ConsoleBuffer` (driver-level, whole screen) both maintain cell grids with different `Cell` types. Evaluate whether these can share a cell representation, or whether the layout buffer can write directly to the driver buffer's coordinate space (eliminating the per-window buffer copy). |
92 | | - |
93 | | ---- |
94 | | - |
95 | | -## 5. Input Responsiveness (Medium Priority) |
96 | | - |
97 | | -### Replace Thread.Sleep with Waitable Event |
98 | | - |
99 | | -The main loop uses `Thread.Sleep(_idleTime)` for frame pacing. When idle, the adaptive sleep can push this to 50ms+, adding perceptible lag to the first keypress after an idle period. |
100 | | - |
101 | | -Replace with `ManualResetEventSlim` or `AutoResetEvent`: |
102 | | -- Input thread signals the event when a key/mouse event arrives |
103 | | -- Main loop waits on the event with timeout (the idle duration) |
104 | | -- First input after idle wakes the loop immediately instead of waiting for the sleep to expire |
105 | | - |
106 | | -This is a small change with noticeable UX improvement. |
107 | | - |
108 | | ---- |
109 | | - |
110 | | -## 6. Missing Controls (Medium Priority) |
111 | | - |
112 | | -Controls that real applications commonly need: |
113 | | - |
114 | | -- **RadioButtonGroup** — exclusive selection from a set (CheckboxControl can't do this alone) |
115 | | -- **NumericSpinner** — increment/decrement number with arrow keys |
116 | | -- **DatePicker / TimePicker** — date/time selection |
117 | | -- **ColorPicker** — color selection dialog |
118 | | -- **StatusBarControl** — per-window status bar (not just the system-level one) |
119 | | -- **SplitPanel** — vertical splitter (HorizontalGrid handles horizontal, but vertical split between two panels is a common need) |
120 | | - |
121 | | -### Data Virtualization |
122 | | - |
123 | | -ListControl, TreeControl, and TableControl appear to hold all items in memory. For large datasets (100K+ rows), add a virtualized data source pattern: |
124 | | -- `IVirtualListSource` — provides count + items-in-range |
125 | | -- Only measure/render visible items |
126 | | -- Scrollbar reflects total count |
127 | | - |
128 | | ---- |
129 | | - |
130 | | -## 7. Driver Abstraction (Medium Priority) |
131 | | - |
132 | | -### ~~Headless/Test Driver~~ (Done) |
133 | | - |
134 | | -`HeadlessConsoleDriver` is now in the main library (`SharpConsoleUI.Drivers`). `MockConsoleDriver` in the test project is a thin subclass. |
135 | | - |
136 | | -### Consider Additional Backends |
137 | | - |
138 | | -The `IConsoleDriver` interface is clean enough to support: |
139 | | -- Windows Console Host (native Win32, not ANSI — for legacy terminals) |
140 | | -- SSH/remote session driver |
141 | | -- Web terminal driver (for browser-based TUI) |
142 | | - |
143 | | -Not urgent, but the abstraction is already there — this is future growth potential. |
144 | | - |
145 | | ---- |
146 | | - |
147 | | -## 8. Documentation Gaps (Low Priority) |
148 | | - |
149 | | -The existing docs are solid (12 files, 200KB+). What's missing: |
150 | | - |
151 | | -- **Custom Control Authoring Guide** — step-by-step guide to creating a new control (blocked by item 3 above) |
152 | | -- **Architecture Overview** — a single diagram showing the rendering pipeline layers, the event flow, and the class relationships |
153 | | -- **Migration/Changelog** — when breaking changes happen (like the color parameter unification), document them clearly |
154 | | -- **Performance Tuning Guide** — when to use frame rate limiting, how to optimize large windows, how to profile with the built-in diagnostics |
155 | | - |
156 | | ---- |
157 | | - |
158 | | -## 9. Testing Gaps (Low Priority) |
159 | | - |
160 | | -Current tests focus heavily on rendering (23 of 51 files). Areas with less coverage: |
161 | | - |
162 | | -- **Control behavior tests** — only 3 control test files exist. Each interactive control should have tests for keyboard handling, mouse handling, and state changes. |
163 | | -- **Builder tests** — verify that builders produce controls with correct properties |
164 | | -- **Theme tests** — verify color resolution cascade works correctly |
165 | | -- **Integration tests** — multi-window scenarios (modal on top of modal, window activation with overlapping, resize with multiple dirty windows) |
166 | | - |
167 | | ---- |
168 | | - |
169 | | -## 10. Minor Cleanup (Low Priority) |
170 | | - |
171 | | -- Remove `FIX` toggle constants after confirming fixes are stable (they've served their purpose as feature flags during development, but permanent `const bool FIX11 = true` is dead code) |
172 | | -- Inconsistent indentation in `Renderer.cs` — some blocks use tabs, some use spaces (visible in the RenderLock guard blocks) |
173 | | -- `Performance` field on `ConsoleWindowSystem` is `public` without a property wrapper — should be `{ get; }` or `{ get; private set; }` |
174 | | -- `Input` field on `ConsoleWindowSystem` same issue |
175 | | -- `Render` property is `{ get; private set; }` with `= null!` — initialized in constructor, could be `{ get; }` with readonly backing |
176 | | - |
177 | | ---- |
178 | | - |
179 | | -## Summary |
180 | | - |
181 | | -| Priority | Item | Effort | Impact | |
182 | | -|----------|------|--------|--------| |
183 | | -| High | Color parameter ordering unification | Small | Prevents every user's first bug | |
184 | | -| High | Class decomposition (Window, WSS, Driver) | Large | Maintainability, contributor onboarding | |
185 | | -| High | ControlBase abstract class | Medium | Unlocks third-party controls | |
186 | | -| Medium | String-to-cell round-trip optimization | Medium | Performance under load | |
187 | | -| Medium | Thread.Sleep -> waitable event | Small | Input responsiveness | |
188 | | -| Medium | Missing common controls | Large | Feature completeness | |
189 | | -| Medium | Data virtualization | Medium | Large dataset support | |
190 | | -| ~~Medium~~ | ~~Headless driver in main library~~ | ~~Small~~ | ~~Done~~ | |
191 | | -| Low | Documentation gaps | Medium | Adoption | |
192 | | -| Low | Testing gaps | Large | Reliability confidence | |
193 | | -| Low | Minor code cleanup | Small | Code quality | |
| 42 | +Have a feature request? [Open a discussion](https://github.com/nickprotop/ConsoleEx/discussions/categories/ideas) or [create an issue](https://github.com/nickprotop/ConsoleEx/issues/new). |
0 commit comments