Files
Terminal.Gui/Examples/UICatalog/Scenarios/MultiColouredTable.cs
Tig 0f72cf8a74 Fixes #4425 - ApplicationImpl internal (#4426)
* Pulled from v2_release

* Refactor migration guide for Terminal.Gui v2

Restructured and expanded the migration guide to provide a comprehensive resource for transitioning from Terminal.Gui v1 to v2. Key updates include:

- Added a Table of Contents for easier navigation.
- Summarized major architectural changes in v2, including the instance-based application model, IRunnable architecture, and 24-bit TrueColor support.
- Updated examples to reflect new patterns, such as initializers replacing constructors and explicit disposal using `IDisposable`.
- Documented changes to the layout system, including the removal of `Absolute`/`Computed` styles and the introduction of `Viewport`.
- Standardized event patterns to use `object sender, EventArgs args`.
- Detailed updates to the Keyboard, Mouse, and Navigation APIs, including configurable key bindings and viewport-relative mouse coordinates.
- Replaced legacy components like `ScrollView` and `ContextMenu` with built-in scrolling and `PopoverMenu`.
- Clarified disposal rules and introduced best practices for resource management.
- Provided a complete migration example and a summary of breaking changes.

This update aims to simplify the migration process by addressing breaking changes, introducing new features, and aligning with modern .NET conventions.

* Refactor to use Application.Instance for lifecycle management

Replaced all occurrences of `ApplicationImpl.Instance` with the new `Application.Instance` property across the codebase to align with the updated application lifecycle model.

Encapsulated the `ApplicationImpl` class by making it `internal`, ensuring it is no longer directly accessible outside its assembly. Introduced the `[Obsolete]` `Application.Instance` property as a backward-compatible singleton for the legacy static `Application` model, while encouraging the use of `Application.Create()` for new code.

Updated `MessageBox` methods to use `Application.Instance` for consistent modal dialog management. Improved documentation to reflect these changes and emphasize the transition to the instance-based application model.

Performed code cleanup in multiple classes to ensure consistency and maintainability. These changes maintain backward compatibility while preparing the codebase for the eventual removal of the legacy `ApplicationImpl` class.

* Fix doc bug

* - Removed obsolete `.cd` class diagram files.
- Introduced `IRunnable` interface for decoupling component execution.
- Added fluent API for running dialogs and retrieving results.
- Enhanced `View` with `App` and `Driver` properties for better decoupling.
- Improved testability with support for mock and real applications.
- Implemented `IDisposable` for proper resource cleanup.
- Replaced `RunnableSessionStack` with `SessionStack` for session management.
- Updated driver architecture to align with the new model.
- Scoped `IKeyboard` to application contexts for modularity.
- Updated documentation with migration strategies and best practices.

These changes modernize the library, improve maintainability, and align with current development practices.
2025-12-01 14:40:31 -07:00

227 lines
7.7 KiB
C#

#nullable enable
using System.Data;
using System.Text;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("MultiColouredTable", "Demonstrates how to multi color cell contents.")]
[ScenarioCategory ("Controls")]
[ScenarioCategory ("Colors")]
[ScenarioCategory ("TableView")]
public class MultiColouredTable : Scenario
{
private DataTable? _table;
private TableViewColors? _tableView;
public override void Main ()
{
Application.Init ();
Window appWindow = new ()
{
Title = GetQuitKeyAndName (),
BorderStyle = LineStyle.None,
};
// MenuBar
var menu = new MenuBar ();
menu.Add (
new MenuBarItem (
"_File",
[
new MenuItem
{
Title = "_Quit",
Action = Quit
}
]
)
);
_tableView = new () { X = 0, Y = Pos.Bottom (menu), Width = Dim.Fill (), Height = Dim.Fill (1) };
// StatusBar
var statusBar = new StatusBar (
[
new (Application.QuitKey, "Quit", Quit)
]
);
appWindow.Add (menu, _tableView, statusBar);
_tableView.CellActivated += EditCurrentCell;
DataTable dt = new ();
dt.Columns.Add ("Col1");
dt.Columns.Add ("Col2");
dt.Rows.Add ("some text", "Rainbows and Unicorns are so fun!");
dt.Rows.Add ("some text", "When it rains you get rainbows");
dt.Rows.Add (DBNull.Value, DBNull.Value);
dt.Rows.Add (DBNull.Value, DBNull.Value);
dt.Rows.Add (DBNull.Value, DBNull.Value);
dt.Rows.Add (DBNull.Value, DBNull.Value);
_tableView.SetScheme (
new ()
{
Disabled = appWindow.GetAttributeForRole (VisualRole.Disabled),
HotFocus = appWindow.GetAttributeForRole (VisualRole.HotFocus),
Focus = appWindow.GetAttributeForRole (VisualRole.Focus),
Normal = new (Color.DarkGray, Color.Black)
}
);
_tableView.Table = new DataTableSource (_table = dt);
Application.Run (appWindow);
appWindow.Dispose ();
Application.Shutdown ();
}
private void EditCurrentCell (object? sender, CellActivatedEventArgs e)
{
if (e.Table is null || _table is null || _tableView is null)
{
return;
}
var oldValue = e.Table [e.Row, e.Col].ToString ();
if (GetText ("Enter new value", e.Table.ColumnNames [e.Col], oldValue ?? "", out string newText))
{
try
{
_table.Rows [e.Row] [e.Col] =
string.IsNullOrWhiteSpace (newText) ? DBNull.Value : newText;
}
catch (Exception ex)
{
MessageBox.ErrorQuery (Application.Instance, 60, 20, "Failed to set text", ex.Message, "Ok");
}
_tableView.Update ();
}
}
private bool GetText (string title, string label, string initialText, out string enteredText)
{
var okPressed = false;
Button ok = new () { Text = "Ok", IsDefault = true };
ok.Accepting += (s, e) =>
{
okPressed = true;
Application.RequestStop ();
};
Button cancel = new () { Text = "Cancel" };
cancel.Accepting += (s, e) => { Application.RequestStop (); };
Dialog d = new () { Title = title, Buttons = [ok, cancel] };
Label lbl = new () { X = 0, Y = 1, Text = label };
TextField tf = new () { Text = initialText, X = 0, Y = 2, Width = Dim.Fill () };
d.Add (lbl, tf);
tf.SetFocus ();
Application.Run (d);
d.Dispose ();
enteredText = okPressed ? tf.Text : string.Empty;
return okPressed;
}
private void Quit () { Application.RequestStop (); }
private class TableViewColors : TableView
{
protected override void RenderCell (Attribute cellColor, string render, bool isPrimaryCell)
{
int unicorns = render.IndexOf ("unicorns", StringComparison.CurrentCultureIgnoreCase);
int rainbows = render.IndexOf ("rainbows", StringComparison.CurrentCultureIgnoreCase);
for (var i = 0; i < render.Length; i++)
{
if (unicorns != -1 && i >= unicorns && i <= unicorns + 8)
{
SetAttribute (new (Color.White, cellColor.Background));
}
if (rainbows != -1 && i >= rainbows && i <= rainbows + 8)
{
int letterOfWord = i - rainbows;
switch (letterOfWord)
{
case 0:
SetAttribute (new (Color.Red, cellColor.Background));
break;
case 1:
SetAttribute (
new (
Color.BrightRed,
cellColor.Background
)
);
break;
case 2:
SetAttribute (
new (
Color.BrightYellow,
cellColor.Background
)
);
break;
case 3:
SetAttribute (new (Color.Green, cellColor.Background));
break;
case 4:
SetAttribute (
new (
Color.BrightGreen,
cellColor.Background
)
);
break;
case 5:
SetAttribute (
new (
Color.BrightBlue,
cellColor.Background
)
);
break;
case 6:
SetAttribute (
new (
Color.BrightCyan,
cellColor.Background
)
);
break;
case 7:
SetAttribute (new (Color.Cyan, cellColor.Background));
break;
}
}
AddRune ((Rune)render [i]);
SetAttribute (cellColor);
}
}
}
}