Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
193 commits
Select commit Hold shift + click to select a range
68d8c7e
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
tig Mar 9, 2026
867f5d8
plan
tig Mar 11, 2026
18695ed
Phase 0: Delete old TabView implementation and fix compilation errors
tig Mar 11, 2026
43b4676
Phase 1: Add Border.Gaps enhancement for TabView border gaps
tig Mar 11, 2026
83b9655
Phase 2: Core TabView, Tab, and TabRow implementation
tig Mar 11, 2026
080cddd
Phase 3: Add TabViews UICatalog scenario
tig Mar 11, 2026
1ba2591
Fix NumericUpDown min/max using ValueChanging pattern
tig Mar 11, 2026
13efc08
TabView rendering: no-top-border architecture, segmented border lines…
tig Mar 12, 2026
3b47d2a
Update plan: mark phases done, add known issues for scrolling and Tab…
tig Mar 12, 2026
ad72c53
Refactor TabViewExample layout, update docs and known issues
tig Mar 12, 2026
c571947
Fix TabsOnBottom rendering, add comprehensive visual tests
tig Mar 12, 2026
6e1e4ce
Add hotkey support and tests for TabView tabs
tig Mar 12, 2026
00d2f87
updated plan
tig Mar 12, 2026
41919a6
Rename TabsOnBottom to TabSide, add hotkey tests, update scenario
tig Mar 12, 2026
e713217
Improve TabView focus, navigation, and add scroll tests
tig Mar 12, 2026
e5bdb10
Add tab scrolling infrastructure: ContentSize, EnsureHeaderVisible, v…
tig Mar 13, 2026
3267b44
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
tig Mar 13, 2026
b4046e4
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 13, 2026
86bfa7b
Add Border-based TabView design plan
tig Mar 13, 2026
f434b17
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 13, 2026
7d191b6
Rewrite tabview-border-based-design: Border-based tabs
tig Mar 13, 2026
5e15f82
WIP: Working on Borders and LineCanvas carap.
tig Mar 13, 2026
4ff0cb1
updated plan
tig Mar 14, 2026
8496105
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 14, 2026
3f6b461
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
tig Mar 14, 2026
f1ef70e
fixed editors
tig Mar 14, 2026
a7f3509
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 15, 2026
8e50623
merged
tig Mar 15, 2026
c101e41
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 23, 2026
1f6b1ee
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 23, 2026
17d0b3b
updated plans
tig Mar 23, 2026
f7d3cd7
Delete existing TabView/TabRow/Tab, BorderGap, tests, and scenario
tig Mar 23, 2026
e02e8b2
Add precise rendering spec for tab border drawings in Phase 1
tig Mar 23, 2026
cfc39ae
Add Bottom/Left/Right TabOffset examples to Phase 1 plan
tig Mar 23, 2026
9ccb885
Enhance Left/Right TabOffset spec with header height, overflow clippi…
tig Mar 23, 2026
038b676
Revise Phase 1 to use general-purpose TabHeaderRenderer with TDD appr…
tig Mar 23, 2026
5fd69b3
Add TabHeaderRenderer: side-agnostic tab header drawing
tig Mar 24, 2026
d676d01
Use rounded borders for tab headers and update tests
tig Mar 24, 2026
e651cdc
Code cleanup
tig Mar 24, 2026
494cb37
Add tests for negative TabOffset in tab header rendering
tig Mar 24, 2026
65afc07
Refactor TabHeaderRenderer: geometry-only, no text drawing
tig Mar 24, 2026
1b72dd4
Add Tab header support to Border and BorderView
tig Mar 24, 2026
2aea291
Add tab header support to Border and BorderView
tig Mar 24, 2026
28c8720
Fix depth=1/2 tab header rendering and add thickness variant tests
tig Mar 24, 2026
d2d5a7d
updated spec.
tig Mar 24, 2026
74e3549
Progress. Updated plan.
tig Mar 24, 2026
77e67ca
Refactor: split Tab border into DrawTabBorder with edge-based positio…
tig Mar 24, 2026
2f4e3cf
Refine tabbed border focus rendering for thin borders
tig Mar 25, 2026
71ac0a8
Code cleanup
tig Mar 25, 2026
b5ccef4
Improve tab header rendering and update tests
tig Mar 25, 2026
923b564
plan
tig Mar 25, 2026
31fdaa2
Hybird approach - simplified -working.
tig Mar 25, 2026
9e0caff
Add failing tests for adornment SubView LineCanvas auto-join bug (#4854)
tig Mar 25, 2026
83e4e7e
Fixes #4854. Adornment SubView LineCanvas auto-join pipeline fix
tig Mar 25, 2026
76d488b
warning cleanup
tig Mar 25, 2026
8649a7b
Another test.
tig Mar 25, 2026
6f478ef
Refactor: Replace custom tab line drawing with Label SubView border
tig Mar 25, 2026
41afab0
Add TabTitleView with focus-aware attributes and hotkey support
tig Mar 25, 2026
da9a6d4
Add tab title drag in Adornments scenario, expose BorderView.TabTitle
tig Mar 25, 2026
61ed768
Merge remote-tracking branch 'origin/v2_develop' into issue-4183-tabview
tig Mar 25, 2026
23ecd9c
Docs and new plan
tig Mar 25, 2026
6ed67ac
progress
tig Mar 26, 2026
5a18752
Border Tab mode: eager config, event, and tests
tig Mar 26, 2026
777b1cb
WIP - fixing weird draw issue
tig Mar 26, 2026
6964cb1
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 26, 2026
8c8ded0
Fixes Region.Combine: zero-width/zero-height rectangles corrupt Union…
tig Mar 26, 2026
2a0c867
tweaks.
tig Mar 26, 2026
3e8d864
Fixed tab rendering.
tig Mar 27, 2026
8841a23
LineCanvas.Merge: PascalCase local functions, early-return style, imp…
tig Mar 27, 2026
510abe8
Initial plan
Copilot Mar 27, 2026
a8f2b59
Add failing test for scrollbar placement with border
Copilot Mar 27, 2026
fa31554
Fix double-increment of Padding.Thickness in scrollbar initialization
Copilot Mar 27, 2026
e1fca8e
tests
tig Mar 27, 2026
3da88d5
cleand up tests.;
tig Mar 27, 2026
bfe2e78
Fixed Tab style all 4 sides.
tig Mar 27, 2026
d56ba80
Add test reproducing DropDownList scrolling bug (top items blank afte…
Copilot Mar 27, 2026
f2125db
Fixed Bottom
tig Mar 27, 2026
93bda5f
updated plan
tig Mar 27, 2026
7e720fd
plan
tig Mar 27, 2026
d560150
Step 1: Add Tab and Tabs views with border-based tab rendering
tig Mar 27, 2026
7a5b4a3
Code cleanup and minor fixes.
tig Mar 27, 2026
0650e91
Update Tabs.EnableForDesign to match TabsExample scenario content
tig Mar 27, 2026
6c0999a
Wire up ValueChanged handlers in Tabs.EnableForDesign
tig Mar 27, 2026
7d2ce7e
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 27, 2026
38d7777
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 27, 2026
8ce2915
tweaks
tig Mar 27, 2026
db68ee1
Merge branch 'v2_develop' into copilot/fix-uicatalog-scenariolist-scr…
tig Mar 28, 2026
6435f9f
code cleanup
tig Mar 28, 2026
8f21718
Fixed?
tig Mar 28, 2026
2782101
Fixed by adding ClearedRegion.
tig Mar 29, 2026
04ca5b6
new plan
tig Mar 29, 2026
60bdbe6
Fix DrawContext ownership: per-view tracking for CachedDrawnRegion
tig Mar 29, 2026
9519672
WIP
tig Mar 29, 2026
25c8e18
Fixed test.
tig Mar 29, 2026
926ec1b
Enhance Tabs: TabDepth, focus, design-time, cleanup
tig Mar 30, 2026
ccb43da
Refactor DrawContext: per-view tracking for hit-testing
tig Mar 30, 2026
c224b86
Refactor DrawContext: per-view tracking for hit-testing
tig Mar 30, 2026
45e226d
Added tests.
tig Mar 30, 2026
02c4ede
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 30, 2026
1dd185a
cleanup
tig Mar 30, 2026
d39402b
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Mar 30, 2026
c3e4269
Merge branch 'v2_develop' into issue-4183-tabview
tig Mar 30, 2026
79e891c
Merged
tig Mar 30, 2026
f1f159c
Merged
tig Mar 30, 2026
f0441d0
Improve line canvas merging and add auto-join tests
tig Mar 30, 2026
30a0c36
Added #if to better illustrate code.
tig Mar 30, 2026
67abe9f
inital plan from copilot
tig Mar 30, 2026
53884e1
udpate: going with Option B: Per-Z-level LineCanvas compositing
tig Mar 30, 2026
0d11173
Overlapped border gaps: reserved cells & Z-aware compositing
tig Mar 30, 2026
8441adc
Code cleanup
tig Mar 30, 2026
365f21d
Clarify LineCanvas docs and line drawing usage
tig Mar 30, 2026
84e0878
Moved LC code out of View.Drawing.cs
tig Mar 30, 2026
6312109
Cleanup
tig Mar 30, 2026
460f4e0
Refctored
tig Mar 31, 2026
8796211
Refactor AdornmentsEditor: tabs, null-safety, robustness
tig Mar 31, 2026
f86586b
Use explicit types, add null checks, clarify event args
tig Mar 31, 2026
ef41062
Refactor: modernize style, null-safety, and constructors
tig Mar 31, 2026
b139c20
Improve null safety and code style in Scheme and bindings
tig Mar 31, 2026
ff6ca2a
Add null check for tab.SuperView in BorderView
tig Mar 31, 2026
75770b2
plan
tig Mar 31, 2026
3281175
Refactor Tabs to support any View, remove Tab class
tig Mar 31, 2026
6653e61
cleanup
tig Mar 31, 2026
d8db88e
Refactor AdornmentsEditor and editors layout/titles
tig Mar 31, 2026
eb3d72b
Refactor Tabs: add OptionSelector as tab, rename tab4
tig Mar 31, 2026
53e9b20
Add InsertTab and enhance Add/Remove tab UI in Tabs
tig Mar 31, 2026
4386626
scrolling plan
tig Mar 31, 2026
0894335
Tweaks
tig Mar 31, 2026
270334e
cleanup
tig Mar 31, 2026
5be8696
Progress
tig Apr 1, 2026
c5463f6
Refactor Tabs scrolling logic and expand side coverage
tig Apr 1, 2026
29c2489
Clamp Tabs scroll offset; add tests and design control
tig Apr 1, 2026
f4c4026
Improve Tabs.ScrollOffset docs and add clamping tests
tig Apr 1, 2026
5c80f85
Refactor Tabs to use per-tab header scrollbars
tig Apr 1, 2026
0da6803
Replace ScrollBar with arrow buttons for tab scrolling
tig Apr 1, 2026
7558f8f
cleanup
tig Apr 1, 2026
bd407ff
Refactor Tabs logic and improve add/remove tab UI
tig Apr 1, 2026
e1c6fb9
Code cleanup
tig Apr 1, 2026
8e83629
Add ScrollButton control; refactor scrollable UI buttons
tig Apr 1, 2026
8fff541
scenario cleanup
tig Apr 1, 2026
d3b666e
Refactor GraphViewExample to use Tabs for each graph
tig Apr 1, 2026
75ac103
better docs
tig Apr 1, 2026
706132f
Cleanup
tig Apr 1, 2026
b941c02
WIP: Broken. Restore and enhance Tabs control with navigation
tig Apr 2, 2026
6bb24ce
Add keyboard arrange mode unit tests and cleanup
tig Apr 3, 2026
4842f47
Generalize command bubbling to all AdornmentViews
tig Apr 3, 2026
0dae898
Add ArrangerButton for Arrange Mode with key binding logic
tig Apr 3, 2026
05bc09b
Make Default*Handler methods public for subclass command registration
tig Apr 3, 2026
80e8519
code cleanup
tig Apr 3, 2026
f7952cd
Replace TabTitleView with TitleView for tab headers
tig Apr 3, 2026
9d3b0eb
nuked old tests
tig Apr 3, 2026
1753029
Add tests for Tabs border rendering and style restore
tig Apr 4, 2026
e548775
Fix TabLineStyle change not restoring tab border thickness
tig Apr 4, 2026
bd81f1e
Add TAB_COLOR_PROTOTYPE for tab color customization
tig Apr 4, 2026
fd955bc
Refactor BorderView TitleView usage and add visual tests
tig Apr 4, 2026
2dc62bb
Add exhaustive tab border rendering tests
tig Apr 4, 2026
8942171
refactor plan
tig Apr 4, 2026
27f86f8
updated plan
tig Apr 4, 2026
b6275cf
tweaks
tig Apr 4, 2026
0241937
tweaks2
tig Apr 4, 2026
b84b038
Refactor Tabs design UI, centering, and code style
tig Apr 4, 2026
ebb2dec
Code review
tig Apr 4, 2026
67a22f0
TitleViewTests
tig Apr 4, 2026
5a101c2
Updates
tig Apr 4, 2026
e25daff
code cleanup
tig Apr 4, 2026
9313375
Refactor tab depth logic to use settable TabDepth property
tig Apr 4, 2026
434ea8f
Update TitleView: auto-update border thickness, add tests
tig Apr 5, 2026
f87ec5b
Fix DimAuto.Calculate returning wrong height for vertical text
tig Apr 5, 2026
d125c0e
Improve tab header measurement for accurate sizing
tig Apr 5, 2026
ecb5686
Fix tab header length recalculation on TabSide change
tig Apr 5, 2026
92921dd
enabled tablength in enablefordesign
tig Apr 5, 2026
db43f47
Does not fix the bug.
tig Apr 6, 2026
7a3c20a
new test proves prior solution was bogus
tig Apr 6, 2026
43a81a8
Pre-warm Wcwidth cache; update line canvas test
tig Apr 6, 2026
f324215
Added comment
tig Apr 6, 2026
0cf5236
Merge branch 'v2_develop' into issue-4183-tabview
tig Apr 6, 2026
f3df07a
merge
tig Apr 6, 2026
3ecbf91
Working on adornemnt rendering bug. Giving up for now.
tig Apr 6, 2026
0ea9ff2
Fixed TitleView nav when focused
tig Apr 6, 2026
114da2b
Improve tab navigation and focus behavior in Tabs
tig Apr 7, 2026
6ed35de
Code cleanup
tig Apr 7, 2026
c3f6d45
Code cleanup
tig Apr 7, 2026
9a4b0b7
API docs and code cleanup
tig Apr 7, 2026
f8d2414
API doc updates
tig Apr 7, 2026
edca716
removed old plan
tig Apr 7, 2026
0825920
Merged
tig Apr 7, 2026
ef27c67
plan
tig Apr 7, 2026
f828be3
Merge branch 'v2_develop' into issue-4183-tabview
tig Apr 7, 2026
fa92154
Move tab properties from Border to BorderView
tig Apr 7, 2026
b5089eb
Merge branch 'issue-4183-tabview' of tig:tig/Terminal.Gui into issue-…
tig Apr 7, 2026
93239f6
Tests
tig Apr 7, 2026
011a883
Refactor tab separator positioning for flexibility
tig Apr 7, 2026
9bb0653
Add Tabs.TabSpacing property for configurable tab header spacing
tig Apr 7, 2026
acaa463
Merge branch 'develop' into issue-4183-tabview
tig Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ dotnet run
**Test:** `dotnet test --project Tests/UnitTests --no-build && dotnet test --project Tests/UnitTestsParallelizable --no-build`
**Details:** [Build & Test Workflow](.claude/workflows/build-test-workflow.md)

### xUnit v3 Test Filtering (Microsoft Testing Platform)

This project uses **xUnit v3** with Microsoft Testing Platform. The old `--filter "FullyQualifiedName~Foo"` syntax does **NOT** work. Use these instead:

```bash
# Run a single test by method name
dotnet test --project Tests/UnitTestsParallelizable --no-build --filter-method "*MyTestMethod"

# Run all tests in a class
dotnet test --project Tests/UnitTestsParallelizable --no-build --filter-class "*MyTestClass"

# Query filter language (xUnit v3 native): /<assembly>/<namespace>/<class>/<method>
dotnet test --project Tests/UnitTestsParallelizable --no-build --filter "/*/*/MyTestClass/MyTestMethod"

# Show live test output (ITestOutputHelper)
dotnet test --project Tests/UnitTestsParallelizable --no-build --filter-method "*MyTest" -- --show-live-output on
```

## Quick Rules

**⚠️ READ THIS BEFORE MODIFYING ANY FILE - These are Terminal.Gui-specific conventions:**
Expand All @@ -68,7 +86,7 @@ dotnet run
3. **Use `[...]`** - Collection expressions, not `new () { ... }`
4. **SubView/SuperView** - Never say "child", "parent", or "container"
5. **Unused lambda params** - Use `_` discard: `(_, _) => { }`
6. **Local functions** - Use camelCase: `void myLocalFunc ()`
6. **Local functions** - Use PascalCase: `void MyLocalFunc ()`
7. **Backing fields** - Place immediately before their property
8. **Early return** - Prefer guard clauses over nested `if`/`else`
9. **One type per file** - Public and internal types each get their own file
Expand Down
2 changes: 1 addition & 1 deletion Examples/UICatalog/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"UICatalog": {
"commandName": "Project",
"commandLineArgs": "--debug-log-level Debug"
"commandLineArgs": "--debug-log-level Trace"
},
"UICatalog --driver windows": {
"commandName": "Project",
Expand Down
86 changes: 80 additions & 6 deletions Examples/UICatalog/Scenarios/Adornments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ public override void Main ()

Window window = new ()
{
Title = "The _Window",
Title = "The _Window - The Title is long",
Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable,
Width = Dim.Fill (adornmentsEditor),
Height = Dim.Fill (viewportSettingsEditor)
X = 5,
Y = 5,
Width = Dim.Fill (adornmentsEditor) - 10,
Height = Dim.Fill (viewportSettingsEditor) - 10
};
appWindow.Add (window);

Expand Down Expand Up @@ -100,14 +102,80 @@ public override void Main ()

window.Margin.GetOrCreateView ();
window.Margin.View?.Text = "Margin Text";
window.Margin.Thickness = new Thickness (2);
window.Margin.Thickness = new Thickness (0);

window.Border.GetOrCreateView ();

//window.Border.View.Text = "Border Text";
window.Border.Thickness = new Thickness (3);
window.Border.View?.SetScheme (SchemeManager.GetScheme (Schemes.Dialog));

window.Border.GetOrCreateView ();
//window.Border.View?.SetScheme (SchemeManager.GetScheme (Schemes.Dialog));

window.Border.Settings = BorderSettings.Tab | BorderSettings.Title;
window.BorderStyle = LineStyle.Rounded;

// Enable dragging the tab title to slide it by changing TabOffset.
// Hook into TitleView.MouseEvent — it fires before the Arranger, so no conflict.
Point? dragStart = null;
var dragStartOffset = 0;
var tabDragHooked = false;

window.DrawComplete += (_, _) =>
{
if (tabDragHooked || ((BorderView)window.Border.View!).TitleView is not { } tabTitle)
{
return;
}

tabDragHooked = true;
var bv = (BorderView)window.Border.View!;

tabTitle.MouseEvent += (_, mouse) =>
{
// Start drag
if (!dragStart.HasValue && mouse.Flags.HasFlag (MouseFlags.LeftButtonPressed))
{
dragStart = mouse.ScreenPosition;
dragStartOffset = bv.TabOffset;
window.App?.Mouse.GrabMouse (tabTitle);
mouse.Handled = true;
}

// Dragging
if (dragStart.HasValue
&& mouse.Flags is (MouseFlags.LeftButtonPressed | MouseFlags.PositionReport))
{
int delta = bv.TabSide is Side.Top or Side.Bottom
? mouse.ScreenPosition.X - dragStart.Value.X
: mouse.ScreenPosition.Y - dragStart.Value.Y;

int tabLen = bv.TabLength ?? 0;

// Content border edge length (the side the tab slides along)
int edgeLen = bv.TabSide is Side.Top or Side.Bottom
? window.Frame.Width
- window.Border.Thickness.Left
- window.Border.Thickness.Right
: window.Frame.Height
- window.Border.Thickness.Top
- window.Border.Thickness.Bottom;

int newOffset = Math.Clamp (dragStartOffset + delta, 1 - tabLen, edgeLen - 1);

bv.TabOffset = newOffset;
mouse.Handled = true;
}

// Release
if (!mouse.Flags.HasFlag (MouseFlags.LeftButtonReleased) || !dragStart.HasValue)
{
return;
}
dragStart = null;
window.App?.Mouse.UngrabMouse ();
mouse.Handled = true;
};
};
window.Padding.View?.Text = "Padding Text line 1\nPadding Text line 3\nPadding Text line 3\nPadding Text line 4\nPadding Text line 5";
window.Padding.Thickness = new Thickness (1);
window.Padding.View?.SetScheme (SchemeManager.GetScheme (Schemes.Menu));
Expand Down Expand Up @@ -180,6 +248,12 @@ public override void Main ()

appWindow.Add (adornmentsEditor, viewportSettingsEditor);

appWindow.DrawingContent += (_, e) =>
{
appWindow.FillRect (appWindow.Viewport, Glyphs.Diamond);
e.Cancel = true;
};

app.Run (appWindow);
}
}
39 changes: 24 additions & 15 deletions Examples/UICatalog/Scenarios/AnsiRequestsScenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,38 @@ public override void Main ()
app.Init ();
_app = app;

TabView tv = new () { Width = Dim.Fill (), Height = Dim.Fill (), CanFocus = true };

Tab single = new ();
single.DisplayText = "Single";
single.View = BuildSingleTab ();

Tab bulk = new ();
bulk.DisplayText = "Multi";
bulk.View = BuildBulkTab ();

tv.AddTab (single, true);
tv.AddTab (bulk, false);
// Restored: Tabs with Single and Bulk tabs (#4183)
View singleView = BuildSingleTab ();
View bulkView = BuildBulkTab ();

// Setup - Create a top-level application window and configure it.
using Window appWindow = new ();
appWindow.Title = GetQuitKeyAndName ();

appWindow.Add (tv);
Tabs tabs = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill ()
};

View singleTab = new () { Title = "_Single" };
singleView.Width = Dim.Fill ();
singleView.Height = Dim.Fill ();
singleTab.Add (singleView);

View bulkTab = new () { Title = "_Bulk" };
bulkView.Width = Dim.Fill ();
bulkView.Height = Dim.Fill ();
bulkTab.Add (bulkView);

tabs.Add (singleTab, bulkTab);
tabs.Value = singleTab;

appWindow.Add (tabs);

// Run - Start the application.
app.Run (appWindow);
bulk.View.Dispose ();
single.View.Dispose ();
tabs.Dispose ();

_app.RemoveTimeout (_updateTimeoutToken!);
_app.RemoveTimeout (_sendDarTimeoutToken!);
Expand Down
1 change: 1 addition & 0 deletions Examples/UICatalog/Scenarios/Arrangement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public override void Main ()
app.Init ();

using Window mainWindow = new ();
mainWindow.SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Dialog);
mainWindow.Title = GetQuitKeyAndName ();
mainWindow.TabStop = TabBehavior.TabGroup;
mainWindow.ShadowStyle = null;
Expand Down
63 changes: 32 additions & 31 deletions Examples/UICatalog/Scenarios/ConfigurationEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
namespace UICatalog.Scenarios;

[ScenarioMetadata ("Configuration Editor", "Edits of Terminal.Gui Config Files")]
[ScenarioCategory ("TabView")]
[ScenarioCategory ("Tabs")]
[ScenarioCategory ("Colors")]
[ScenarioCategory ("Files and IO")]
[ScenarioCategory ("TextView")]
[ScenarioCategory ("Configuration")]
public class ConfigurationEditor : Scenario
{
private TabView? _tabView;
private Tabs? _tabs;
private Shortcut? _lenShortcut;
private IApplication? _app;

Expand Down Expand Up @@ -41,14 +41,12 @@ public override void Main ()

StatusBar statusBar = new ([quitShortcut, reloadShortcut, saveShortcut, _lenShortcut]);

_tabView = new TabView { Width = Dim.Fill (), Height = Dim.Fill (to: statusBar) };
_tabs = new Tabs { Width = Dim.Fill (), Height = Dim.Fill (statusBar) };

win.Add (_tabView, statusBar);

win.IsModalChanged += (_, _) => { Open (); };
win.Add (_tabs, statusBar);

ConfigurationManager.Applied += ConfigurationManagerOnApplied;

Open ();
app.Run (win);

return;
Expand Down Expand Up @@ -84,40 +82,43 @@ private void Open ()
editor.Title = "HardCoded";
}

Tab tab = new () { View = editor, DisplayText = config.Key.ToString () };
View tab = new () { Title = config.Key.ToString () };
tab.Add (editor);

_tabView!.AddTab (tab, false);
_tabs?.Add (tab);

editor.Read ();

editor.ContentsChanged += (_, _) =>
{
_lenShortcut!.Title = _lenShortcut!.Title.Replace ("*", "");

if (editor.IsDirty)
{
_lenShortcut!.Title += "*";
}
};
//editor.ContentsChanged += OnEditorOnContentsChanged;

_lenShortcut!.Title = $"{editor.Title}";
_lenShortcut?.Title = $"{editor.Title}";
}

_tabView!.SelectedTabChanged += (_, args) => { _lenShortcut!.Title = $"{args.NewTab.View!.Title}"; };
_tabs?.ValueChanged += (_, args) =>
{
ConfigTextView? editor = args.NewValue?.SubViews.OfType<ConfigTextView> ().FirstOrDefault ();

if (editor is { })
{
_lenShortcut!.Title = $"{editor.Title}";
}
};
}

private void OnEditorOnContentsChanged (object? o, ContentsChangedEventArgs contentsChangedEventArgs)
{
var editor = (ConfigTextView)o!;
_lenShortcut?.Title = _lenShortcut.Title.Replace ("*", "");

if (editor.IsDirty)
{
_lenShortcut?.Title += "*";
}
}

private void Quit ()
{
foreach (ConfigTextView editor in _tabView!.Tabs.Select (v =>
{
if (v.View is ConfigTextView ctv)
{
return ctv;
}

return null;
})
.Cast<ConfigTextView> ())
foreach (ConfigTextView editor in _tabs?.TabCollection.SelectMany (t => t.SubViews.OfType<ConfigTextView> ()) ?? [])
{
if (!editor.IsDirty)
{
Expand All @@ -139,7 +140,7 @@ private void Quit ()
}
}

_tabView?.App?.RequestStop ();
_tabs?.App?.RequestStop ();
}

private void Reload ()
Expand Down
32 changes: 22 additions & 10 deletions Examples/UICatalog/Scenarios/Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public class Editor : Scenario
private CheckBox? _miForceMinimumPosToZeroCheckBox;
private byte []? _originalText;
private bool _saved = true;
private TabView? _tabView;
private string _textToFind = string.Empty;
private string _textToReplace = string.Empty;
private TextView? _textView;
Expand Down Expand Up @@ -935,16 +934,14 @@ private void SetFindText ()

private void ShowFindReplace (bool isFind = true)
{
if (_findReplaceWindow is null || _tabView is null)
if (_findReplaceWindow is null)
{
return;
}

_findReplaceWindow.Visible = true;
_findReplaceWindow.SuperView?.MoveSubViewToStart (_findReplaceWindow);
_tabView.SetFocus ();
_tabView.SelectedTab = isFind ? _tabView.Tabs.ToArray () [0] : _tabView.Tabs.ToArray () [1];
_tabView.SelectedTab?.View?.FocusDeepest (NavigationDirection.Forward, null);
_findReplaceWindow.FocusDeepest (NavigationDirection.Forward, null);
}

private void CreateFindReplace ()
Expand All @@ -956,14 +953,29 @@ private void CreateFindReplace ()

_findReplaceWindow = new FindReplaceWindow (_textView);

_tabView = new TabView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill (0) };
// Restored: Tabs with Find and Replace tabs (#4183)
Tabs tabs = new ()
{
Width = Dim.Fill (),
Height = Dim.Fill ()
};

View findTab = new () { Title = "_Find" };
View findView = CreateFindTab ();
findView.Width = Dim.Fill ();
findView.Height = Dim.Fill ();
findTab.Add (findView);

_tabView.AddTab (new Tab { DisplayText = "Find", View = CreateFindTab () }, true);
_tabView.AddTab (new Tab { DisplayText = "Replace", View = CreateReplaceTab () }, false);
View replaceTab = new () { Title = "_Replace" };
View replaceView = CreateReplaceTab ();
replaceView.Width = Dim.Fill ();
replaceView.Height = Dim.Fill ();
replaceTab.Add (replaceView);

_tabView.SelectedTabChanged += (s, e) => { _tabView.SelectedTab?.View?.FocusDeepest (NavigationDirection.Forward, null); };
tabs.Add (findTab, replaceTab);
tabs.Value = findTab;

_findReplaceWindow.Add (_tabView);
_findReplaceWindow.Add (tabs);
_findReplaceWindow.Visible = false;
_appWindow.Add (_findReplaceWindow);
}
Expand Down
Loading