From 7e2e7b9d2db0e7c7f0fff819bcb39dae63043293 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 28 Jul 2022 09:31:26 -0400 Subject: [PATCH] Updates v1.7 docs (#1919) * updated readmes * Updated doc visual style & regenerated * updated relnotes --- README.md | 79 +++--------- Terminal.Gui/Terminal.Gui.csproj | 1 + docfx/articles/drivers.md | 8 ++ docfx/articles/index.md | 1 + docfx/articles/keyboard.md | 12 ++ docfx/articles/mainloop.md | 6 +- docfx/articles/overview.md | 32 +++-- docfx/index.md | 1 + docfx/templates/default/styles/main.css | 2 +- .../Terminal.Gui.Application.html | 1 - docs/articles/drivers.html | 118 ++++++++++++++++++ docs/articles/index.html | 1 + docs/articles/keyboard.html | 6 + docs/articles/mainloop.html | 1 + docs/articles/overview.html | 20 +-- docs/index.html | 1 + docs/index.json | 15 ++- docs/manifest.json | 30 +++-- docs/styles/main.css | 2 +- 19 files changed, 225 insertions(+), 112 deletions(-) create mode 100644 docfx/articles/drivers.md create mode 100644 docs/articles/drivers.html diff --git a/README.md b/README.md index cb4aaa1f4..8ad09dcfd 100644 --- a/README.md +++ b/README.md @@ -10,43 +10,20 @@ A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix. -![Sample app](https://raw.githubusercontent.com/gui-cs/Terminal.Gui/docfx/sample.gif) +![Sample app](https://raw.githubusercontent.com/gui-cs/Terminal.Gui/docfx/images/sample.gif) -## Controls and Views -*Terminal.Gui* provides a rich set of views and controls for building terminal user interfaces: +## Documentation -* [Button](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Button.html) - A View that provides an item that invokes an System.Action when activated by the user. -* [CheckBox](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.CheckBox.html) - Shows an on/off toggle that the user can set. -* [ColorPicker](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ColorPicker.html) - Enables to user to pick a color. -* [ComboBox](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ComboBox.html) - Provides a drop-down list of items the user can select from. -* [Dialog](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Dialog.html) - A pop-up Window that contains one or more Buttons. - * [OpenDialog](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.OpenDialog.html) - A Dialog providing an interactive pop-up Window for users to select files or directories. - * [SaveDialog](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.SaveDialog.html) - A Dialog providing an interactive pop-up Window for users to save files. -* [FrameView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.FrameView.html) - A container View that draws a frame around its contents. Similar to a GroupBox in Windows. -* [GraphView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.GraphView.html) - A View for rendering graphs (bar, scatter etc). -* [Hex viewer/editor](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.HexView.html) - A hex viewer and editor that operates over a file stream. -* [Label](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Label.html) - Displays a string at a given position and supports multiple lines. -* [ListView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ListView.html) - Displays a scrollable list of data where each item can be activated to perform an action. -* [MenuBar](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.MenuBar.html) - Provides a menu bar with drop-down and cascading menus. -* [MessageBox](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.MessageBox.html) - Displays a modal (pup-up) message to the user, with a title, a message and a series of options that the user can choose from. -* [ProgressBar](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ProgressBar.html) - Displays a progress Bar indicating progress of an activity. -* [RadioGroup](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.RadioGroup.html) - Displays a group of labels each with a selected indicator. Only one of those can be selected at a given time -* [ScrollView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ScrollView.html) - Present a window into a virtual space where subviews are added. Similar to the iOS UIScrollView. -* [ScrollBarView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.ScrollBarView.html) - display a 1-character scrollbar, either horizontal or vertical. -* [StatusBar](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.StatusBar.html) - A View that snaps to the bottom of a Toplevel displaying set of status items. Includes support for global app keyboard shortcuts. -* [TableView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TableView.html) - A View for tabular data based on a System.Data.DataTable. -* [TimeField](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TimeField.html) & [DateField](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TimeField.html) - Enables structured editing of dates and times. -* [TextField](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TextField.html) - Provides a single-line text entry. -* [TextValidateField](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TextValidateField.html) - Text field that validates input through a ITextValidateProvider. -* [TextView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TextView.html)- A multi-line text editing View supporting word-wrap, auto-complete, context menus, undo/redo, and clipboard operations, -* [TopLevel](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Toplevel.html) - The base class for modal/pop-up Windows. -* [TreeView](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.TreeView.html) - A hierarchical tree view with expandable branches. Branch objects are dynamically determined when expanded using a user defined ITreeBuilder. -* [View](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.View.html) - The base class for all views on the screen and represents a visible element that can render itself and contains zero or more nested views. -* [Window](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Window.html) - A Toplevel view that draws a border around its Frame with a title at the top. -* [Wizard](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.Wizard.html) - Provides navigation and a user interface to collect related data across multiple steps. +* [Documentation Home](https://gui-cs.github.io/Terminal.Gui/index.html) +* [Terminal.Gui Overview](https://gui-cs.github.io/Terminal.Gui/articles/overview.html) +* [List of Views/Controls](https://gui-cs.github.io/Terminal.Gui/views.html) +* [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/articles/index.html) +* [API Documentation](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.html) -### Features +_The Documentation matches the most recent Nuget release from the `main` branch ([![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui))_ + +## Features * **Cross Platform** - Windows, Mac, and Linux. Terminal drivers for Curses, [Windows Console](https://github.com/gui-cs/Terminal.Gui/issues/27), and the .NET Console mean apps will work well on both color and monochrome terminals. * **Keyboard and Mouse Input** - Both keyboard and mouse input are supported, including support for drag & drop. @@ -57,28 +34,6 @@ A toolkit for building rich console apps for .NET, .NET Core, and Mono that work descriptors. Most classes are safe for threading. * **Reactive Extensions** - Use [reactive extensions](https://github.com/dotnet/reactive) and benefit from increased code readability, and the ability to apply the MVVM pattern and [ReactiveUI](https://www.reactiveui.net/) data bindings. See the [source code](https://github.com/gui-cs/Terminal.Gui/tree/master/ReactiveExample) of a sample app in order to learn how to achieve this. -### Keyboard Input Handling - -**Terminal.Gui** respects common Linux, Mac, and Windows keyboard idioms. For example, clipboard operations use the familiar `Control/Command-C, X, V` model. `CTRL-Q` is used for exiting views (and apps). - -The input handling of **Terminal.Gui** is similar in some ways to Emacs and the Midnight Commander, so you can expect some of the special key combinations to be active. - -The key `ESC` can act as an Alt modifier (or Meta in Emacs parlance), to allow input on terminals that do not have an alt key. So to produce the sequence `Alt-F`, you can press either `Alt-F`, or `ESC` followed by the key `F`. - -To enter the key `ESC`, you can either press `ESC` and wait 100 milliseconds, or you can press `ESC` twice. - -`ESC-0`, and `ESC-1` through `ESC-9` have a special meaning, they map to `F10`, and `F1` to `F9` respectively. - -Apps can change key bindings using the `AddKeyBinding` API. - -### Driver Model - -**Terminal.Gui** has support for [ncurses](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs), [`System.Console`](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/NetDriver.cs), and a full [Win32 Console](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs) front-end. - -`ncurses` is used on Mac/Linux/Unix with color support based on what your library is compiled with; the Windows driver supports full color and mouse, and an easy-to-debug `System.Console` can be used on Windows and Unix, but lacks mouse support. - -You can force the use of `System.Console` on Unix as well; see `Core.cs`. - ## Showcase & Examples * **[UI Catalog](https://github.com/gui-cs/Terminal.Gui/tree/master/UICatalog)** - The UI Catalog project provides an easy to use and extend sample illustrating the capabilities of **Terminal.Gui**. Run `dotnet run --project UICatalog` to run the UI Catalog. @@ -90,15 +45,9 @@ You can force the use of `System.Console` on Unix as well; see `Core.cs`. * **[PoshRedisViewer](https://github.com/En3Tho/PoshRedisViewer)** - A compact Redis viewer module for PowerShell written in F# and Gui.cs * **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications. -## Documentation - -* [Overview](https://gui-cs.github.io/Terminal.Gui/articles/overview.html) -* [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/articles/index.html) -* [API Documentation](https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui/Terminal.Gui.html) - See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. The [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/articles/index.html) provides insight into core concepts. -### Sample Usage +## Sample Usage (This code uses C# 9.0 [Top-level statements](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9#top-level-statements).) ```csharp using Terminal.Gui; @@ -206,6 +155,8 @@ To install Terminal.Gui into a .NET Core project, use the `dotnet` CLI tool with dotnet add package Terminal.Gui ``` +See [CONTRIBUTING.md](CONTRIBUTING.md) for instructions for downloading and forking the source. + ## Running and Building * Windows, Mac, and Linux - Build and run using the .NET SDK command line tools (`dotnet build` in the root directory). Run `UICatalog` with `dotnet run --project UICatalog`. @@ -225,6 +176,4 @@ The original **gui.cs** was a UI toolkit in a single file and tied to curses. Th A presentation of this was part of the [Retro.NET](https://channel9.msdn.com/Events/dotnetConf/2018/S313) talk at .NET Conf 2018 [Slides](https://tirania.org/Retro.pdf) -Release history can be found in the [Terminal.Gui.csproj](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/Terminal.Gui.csproj) file. - -In 2019, 2020, and 2021, Charlie Kindel (https://github.com/tig), @BDisp (https://github.com/BDisp), and Thomas Nind (https://github.com/tznind) vastly extended, improved, polished and fixed gui.cs to what it is today. +The most recent release notes can be found in the [Terminal.Gui.csproj](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/Terminal.Gui.csproj) file. diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index 4f66cacbf..bcbc80d80 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -83,6 +83,7 @@ * Moved Terminal.Gui (and NStack) to the github.com/gui-cs organization. * Adds multi-step Wizard View for setup experiences (#124) * The synchronization context method Send is now blocking (#1854). + * Fixes #1917. Sometimes Clipboard.IsSupported doesn't return the correct * Fixes #1893: Fix URLs to match gui-cs Org * Fixes #1883. Child TopLevels now get Loaded/Ready events. * Fixes #1867, #1866, #1796. TextView enhancements for ReadOnly and WordWrap. diff --git a/docfx/articles/drivers.md b/docfx/articles/drivers.md new file mode 100644 index 000000000..121723645 --- /dev/null +++ b/docfx/articles/drivers.md @@ -0,0 +1,8 @@ + +# Cross-Platform Driver Model + +**Terminal.Gui** has support for [ncurses](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs), [`System.Console`](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/NetDriver.cs), and a full [Win32 Console](https://github.com/gui-cs/Terminal.Gui/blob/master/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs) front-end. + +`ncurses` is used on Mac/Linux/Unix with color support based on what your library is compiled with; the Windows driver supports full color and mouse, and an easy-to-debug `System.Console` can be used on Windows and Unix, but lacks mouse support. + +You can force the use of `System.Console` on Unix as well; see `Core.cs`. \ No newline at end of file diff --git a/docfx/articles/index.md b/docfx/articles/index.md index a569f2386..51e672d7e 100644 --- a/docfx/articles/index.md +++ b/docfx/articles/index.md @@ -4,5 +4,6 @@ * [List of Views](views.md) * [Keyboard Event Processing](keyboard.md) * [Event Processing and the Application Main Loop](mainloop.md) +* [Cross-platform Driver Model](drivers.md) * [TableView Deep Dive](tableview.md) * [TreeView Deep Dive](treeview.md) diff --git a/docfx/articles/keyboard.md b/docfx/articles/keyboard.md index e2927e50d..9fe3b0ee4 100644 --- a/docfx/articles/keyboard.md +++ b/docfx/articles/keyboard.md @@ -1,6 +1,18 @@ Keyboard Event Processing ========================= +**Terminal.Gui** respects common Linux, Mac, and Windows keyboard idioms. For example, clipboard operations use the familiar `Control/Command-C, X, V` model. `CTRL-Q` is used for exiting views (and apps). + +The input handling of **Terminal.Gui** is similar in some ways to Emacs and the Midnight Commander, so you can expect some of the special key combinations to be active. + +The key `ESC` can act as an Alt modifier (or Meta in Emacs parlance), to allow input on terminals that do not have an alt key. So to produce the sequence `Alt-F`, you can press either `Alt-F`, or `ESC` followed by the key `F`. + +To enter the key `ESC`, you can either press `ESC` and wait 100 milliseconds, or you can press `ESC` twice. + +`ESC-0`, and `ESC-1` through `ESC-9` have a special meaning, they map to `F10`, and `F1` to `F9` respectively. + +Apps can change key bindings using the `AddKeyBinding` API. + Keyboard events are sent by the [Main Loop](mainloop.md) to the Application class for processing. The keyboard events are sent exclusively to the current `Toplevel`, this being either the default diff --git a/docfx/articles/mainloop.md b/docfx/articles/mainloop.md index adb648735..47b2dea23 100644 --- a/docfx/articles/mainloop.md +++ b/docfx/articles/mainloop.md @@ -1,5 +1,6 @@ -Event Processing and the Application Main Loop -============================================== +# Event Processing and the Application Main Loop + +_See also [Cross-platform Driver Model](drivers.md)_ The method `Application.Run` that we covered before will wait for events from either the keyboard or mouse and route those events to the @@ -41,7 +42,6 @@ The keyboard inputs is dispatched by the application class to the current TopLevel window this is covered in more detail in the [Keyboard Event Processing](keyboard.md) document. - Async Execution --------------- diff --git a/docfx/articles/overview.md b/docfx/articles/overview.md index f030c279e..983c2a201 100644 --- a/docfx/articles/overview.md +++ b/docfx/articles/overview.md @@ -102,8 +102,7 @@ class Demo { } ``` -Views -===== +## Views All visible elements on a Terminal.Gui application are implemented as [Views](~/api/Terminal.Gui/Terminal.Gui.View.yml). Views are self-contained objects that take care of displaying themselves, can receive keyboard and mouse input and participate in the focus mechanism. @@ -138,8 +137,7 @@ void SetupMyView (View myView) The container of a given view is called the `SuperView` and it is a property of every View. -Layout ------- +## Layout `Terminal.Gui` supports two different layout systems, absolute and computed \ (controlled by the [`LayoutStyle`](~/api/Terminal.Gui/Terminal.Gui.LayoutStyle.yml) @@ -220,7 +218,7 @@ view.Height = Dim.Percent(20) - 1; anotherView.Height = Dim.Height (view)+1 ``` -# TopLevels, Windows and Dialogs. +## TopLevels, Windows and Dialogs. Among the many kinds of views, you typically will create a [Toplevel](~/api/Terminal.Gui/Terminal.Gui.Toplevel.yml) view (or any of its subclasses, like [Window](~/api/Terminal.Gui/Terminal.Gui.Window.yml) or [Dialog](~/api/Terminal.Gui/Terminal.Gui.Dialog.yml) which is special kind of views @@ -229,7 +227,7 @@ only when the user chooses to complete their work there. The following sections cover the differences. -## TopLevel Views +### TopLevel Views [Toplevel](~/api/Terminal.Gui/Terminal.Gui.Toplevel.yml) views have no visible user interface elements and occupy an arbitrary portion of the screen. @@ -281,15 +279,13 @@ class Demo { } ``` -Window Views ------------- +### Window Views [Window](~/api/Terminal.Gui/Terminal.Gui.Window.yml) views extend the Toplevel view by providing a frame and a title around the toplevel - and can be moved on the screen with the mouse (caveat: code is currently disabled) From a user interface perspective, you might have more than one Window on the screen at a given time. -Dialogs -------- +### Dialogs [Dialog](~/api/Terminal.Gui/Terminal.Gui.Dialog.yml) are [Window](~/api/Terminal.Gui/Terminal.Gui.Window.yml) objects that happen to be centered in the middle of the screen. @@ -318,8 +314,7 @@ Which will show something like this: +------------------------------------------------------+ ``` -Running Modally ---------------- +### Running Modally To run your Dialog, Window or Toplevel modally, you will invoke the `Application.Run` method on the toplevel. It is up to your code and event handlers to invoke the `Application.RequestStop()` method to terminate the modal execution. @@ -350,8 +345,7 @@ There is no return value from running modally, so your code will need to have a of indicating the reason that the execution of the modal dialog was completed, in the case above, the `okpressed` value is set to true if the user pressed or selected the Ok button. -Input Handling -============== +## Input Handling Every view has a focused view, and if that view has nested views, one of those is the focused view. This is called the focus chain, and at any given time, only one @@ -385,8 +379,7 @@ to background views when a modal view is running. More details are available on the [`Keyboard Event Processing`](keyboard.md) document. -Colors and Color Schemes -======================== +## Colors and Color Schemes All views have been configured with a color scheme that will work both in color terminals as well as the more limited black and white terminals. @@ -423,7 +416,10 @@ var label = new Label (...); label.TextColor = myColor ``` -MainLoop, Threads and Input Handling -==================================== +## MainLoop, Threads and Input Handling Detailed description of the mainloop is described on the [Event Processing and the Application Main Loop](~/articles/mainloop.md) document. + +## Cross-Platform Drivers + +See [Cross-platform Driver Model](drivers.md). diff --git a/docfx/index.md b/docfx/index.md index b4eca70f1..d28eebea6 100644 --- a/docfx/index.md +++ b/docfx/index.md @@ -13,6 +13,7 @@ A toolkit for building rich console apps for .NET, .NET Core, and Mono that work * [Terminal.Gui API Overview](~/articles/overview.md) * [Keyboard Event Processing](~/articles/keyboard.md) * [Event Processing and the Application Main Loop](~/articles/mainloop.md) +* [Cross-platform Driver Model](~/articles/drivers.md) * [TableView Deep Dive](~/articles/tableview.md) * [TreeView Deep Dive](~/articles/treeview.md) diff --git a/docfx/templates/default/styles/main.css b/docfx/templates/default/styles/main.css index 0d28db9c8..01bd6f07e 100644 --- a/docfx/templates/default/styles/main.css +++ b/docfx/templates/default/styles/main.css @@ -29,7 +29,7 @@ code,kbd,pre,samp{ button, a { - color: var(--highlight-dark); + color: var(--highlight-light); cursor: pointer; } diff --git a/docs/api/Terminal.Gui/Terminal.Gui.Application.html b/docs/api/Terminal.Gui/Terminal.Gui.Application.html index 7567097c4..7ef02ce8a 100644 --- a/docs/api/Terminal.Gui/Terminal.Gui.Application.html +++ b/docs/api/Terminal.Gui/Terminal.Gui.Application.html @@ -989,7 +989,6 @@ Runs the application by calling Declaration
public static void Run<T>(Func<Exception, bool> errorHandler = null)
-
     where T : Toplevel, new()
Parameters
diff --git a/docs/articles/drivers.html b/docs/articles/drivers.html new file mode 100644 index 000000000..b913f609e --- /dev/null +++ b/docs/articles/drivers.html @@ -0,0 +1,118 @@ + + + + + + + + Cross-Platform Driver Model + + + + + + + + + + + + + + + + +
+
+ +
+
+
+ + + + + +
+
+
+
+ +
+
+
+
+
+ +
+
+
    +
  • +
+
+
+
+
+ +
+
Search Results for
+
+

+
+
    +
    +
    +
    +
    +
    +
    +

    Cross-Platform Driver Model

    + +

    Terminal.Gui has support for ncurses, System.Console, and a full Win32 Console front-end.

    +

    ncurses is used on Mac/Linux/Unix with color support based on what your library is compiled with; the Windows driver supports full color and mouse, and an easy-to-debug System.Console can be used on Windows and Unix, but lacks mouse support.

    +

    You can force the use of System.Console on Unix as well; see Core.cs.

    +
    +
    + +
    +
    +
    +
      +
    • + Improve this Doc +
    • +
    +
    +
    +
    In This Article
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + Back to top + + + Generated by DocFX +
    +
    +
    +
    + + + + + + diff --git a/docs/articles/index.html b/docs/articles/index.html index c005faf92..39862acdc 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -78,6 +78,7 @@
  • List of Views
  • Keyboard Event Processing
  • Event Processing and the Application Main Loop
  • +
  • Cross-platform Driver Model
  • TableView Deep Dive
  • TreeView Deep Dive
  • diff --git a/docs/articles/keyboard.html b/docs/articles/keyboard.html index d4f973211..df125b829 100644 --- a/docs/articles/keyboard.html +++ b/docs/articles/keyboard.html @@ -73,6 +73,12 @@

    Keyboard Event Processing

    +

    Terminal.Gui respects common Linux, Mac, and Windows keyboard idioms. For example, clipboard operations use the familiar Control/Command-C, X, V model. CTRL-Q is used for exiting views (and apps).

    +

    The input handling of Terminal.Gui is similar in some ways to Emacs and the Midnight Commander, so you can expect some of the special key combinations to be active.

    +

    The key ESC can act as an Alt modifier (or Meta in Emacs parlance), to allow input on terminals that do not have an alt key. So to produce the sequence Alt-F, you can press either Alt-F, or ESC followed by the key F.

    +

    To enter the key ESC, you can either press ESC and wait 100 milliseconds, or you can press ESC twice.

    +

    ESC-0, and ESC-1 through ESC-9 have a special meaning, they map to F10, and F1 to F9 respectively.

    +

    Apps can change key bindings using the AddKeyBinding API.

    Keyboard events are sent by the Main Loop to the Application class for processing. The keyboard events are sent exclusively to the current Toplevel, this being either the default diff --git a/docs/articles/mainloop.html b/docs/articles/mainloop.html index afd736da4..b12a48daf 100644 --- a/docs/articles/mainloop.html +++ b/docs/articles/mainloop.html @@ -73,6 +73,7 @@

    Event Processing and the Application Main Loop

    +

    See also Cross-platform Driver Model

    The method Application.Run that we covered before will wait for events from either the keyboard or mouse and route those events to the proper view.

    diff --git a/docs/articles/overview.html b/docs/articles/overview.html index bb7bceb4e..ae34d67c5 100644 --- a/docs/articles/overview.html +++ b/docs/articles/overview.html @@ -157,7 +157,7 @@ class Demo { Application.Shutdown (); } } -

    Views

    +

    Views

    All visible elements on a Terminal.Gui application are implemented as Views. Views are self-contained objects that take care of displaying themselves, can receive keyboard and mouse input and participate in the focus mechanism.

    See the full list of Views provided by the Terminal.Gui library here.

    @@ -246,13 +246,13 @@ view.Width = Dim.Fill () - 10; view.Height = Dim.Percent(20) - 1; anotherView.Height = Dim.Height (view)+1 -

    TopLevels, Windows and Dialogs.

    +

    TopLevels, Windows and Dialogs.

    Among the many kinds of views, you typically will create a Toplevel view (or any of its subclasses, like Window or Dialog which is special kind of views that can be executed modally - that is, the view can take over all input and returns only when the user chooses to complete their work there.

    The following sections cover the differences.

    -

    TopLevel Views

    +

    TopLevel Views

    Toplevel views have no visible user interface elements and occupy an arbitrary portion of the screen.

    You would use a toplevel Modal view for example to launch an entire new experience in your application, one where you would have a new top-level menu for example. You typically would add a Menu and a Window to your Toplevel, it would look like this:

    @@ -298,10 +298,10 @@ class Demo { Application.Shutdown (); } } -

    Window Views

    +

    Window Views

    Window views extend the Toplevel view by providing a frame and a title around the toplevel - and can be moved on the screen with the mouse (caveat: code is currently disabled)

    From a user interface perspective, you might have more than one Window on the screen at a given time.

    -

    Dialogs

    +

    Dialogs

    Dialog are Window objects that happen to be centered in the middle of the screen.

    Dialogs are instances of a Window that are centered in the screen, and are intended to be used modally - that is, they run, and they are expected to return a result @@ -320,7 +320,7 @@ var dialog = new Dialog ("Quit", 60, 7, ok, cancel); | | | [ Ok ] [ Cancel ] | +------------------------------------------------------+ -

    Running Modally

    +

    Running Modally

    To run your Dialog, Window or Toplevel modally, you will invoke the Application.Run method on the toplevel. It is up to your code and event handlers to invoke the Application.RequestStop() method to terminate the modal execution.

    bool okpressed = false;
    @@ -345,7 +345,7 @@ if (okpressed)
     

    There is no return value from running modally, so your code will need to have a mechanism of indicating the reason that the execution of the modal dialog was completed, in the case above, the okpressed value is set to true if the user pressed or selected the Ok button.

    -

    Input Handling

    +

    Input Handling

    Every view has a focused view, and if that view has nested views, one of those is the focused view. This is called the focus chain, and at any given time, only one View has the focus.

    @@ -374,7 +374,7 @@ currently focused view.

    view on the screen. The only exception is that no mouse events are delivered to background views when a modal view is running.

    More details are available on the Keyboard Event Processing document.

    -

    Colors and Color Schemes

    +

    Colors and Color Schemes

    All views have been configured with a color scheme that will work both in color terminals as well as the more limited black and white terminals.

    The various styles are captured in the Colors class which defined color schemes for @@ -399,8 +399,10 @@ attribute for a particular pair of Foreground/Background like this:

    var myColor = Application.Driver.MakeAttribute (Color.Blue, Color.Red);
     var label = new Label (...);
     label.TextColor = myColor
    -

    MainLoop, Threads and Input Handling

    +

    MainLoop, Threads and Input Handling

    Detailed description of the mainloop is described on the Event Processing and the Application Main Loop document.

    +

    Cross-Platform Drivers

    +

    See Cross-platform Driver Model.

    diff --git a/docs/index.html b/docs/index.html index a8749957d..6f3c04ed4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -85,6 +85,7 @@
  • Terminal.Gui API Overview
  • Keyboard Event Processing
  • Event Processing and the Application Main Loop
  • +
  • Cross-platform Driver Model
  • TableView Deep Dive
  • TreeView Deep Dive
  • diff --git a/docs/index.json b/docs/index.json index 49b604bfa..ba5f5e492 100644 --- a/docs/index.json +++ b/docs/index.json @@ -1264,25 +1264,30 @@ "title": "Class UICatalogApp", "keywords": "Class UICatalogApp Inheritance System.Object UICatalogApp Namespace : UICatalog Assembly : UICatalog.dll Syntax public class UICatalogApp : Object Constructors UICatalogApp() Declaration public UICatalogApp()" }, + "articles/drivers.html": { + "href": "articles/drivers.html", + "title": "Cross-Platform Driver Model", + "keywords": "Cross-Platform Driver Model Terminal.Gui has support for ncurses , System.Console , and a full Win32 Console front-end. ncurses is used on Mac/Linux/Unix with color support based on what your library is compiled with; the Windows driver supports full color and mouse, and an easy-to-debug System.Console can be used on Windows and Unix, but lacks mouse support. You can force the use of System.Console on Unix as well; see Core.cs ." + }, "articles/index.html": { "href": "articles/index.html", "title": "Conceptual Documentation", - "keywords": "Conceptual Documentation Terminal.Gui Overview List of Views Keyboard Event Processing Event Processing and the Application Main Loop TableView Deep Dive TreeView Deep Dive" + "keywords": "Conceptual Documentation Terminal.Gui Overview List of Views Keyboard Event Processing Event Processing and the Application Main Loop Cross-platform Driver Model TableView Deep Dive TreeView Deep Dive" }, "articles/keyboard.html": { "href": "articles/keyboard.html", "title": "Keyboard Event Processing", - "keywords": "Keyboard Event Processing Keyboard events are sent by the Main Loop to the Application class for processing. The keyboard events are sent exclusively to the current Toplevel , this being either the default that is created when you call Application.Init , or one that you created an passed to Application.Run(Toplevel) . Flow Keystrokes are first processes as hotkeys, then as regular keys, and there is a final cold post-processing event that is invoked if no view processed the key. HotKey Processing Events are first send to all views as a \"HotKey\", this means that the View.ProcessHotKey method is invoked on the current toplevel, which in turns propagates this to all the views in the hierarchy. If any view decides to process the event, no further processing takes place. This is how hotkeys for buttons are implemented. For example, the keystroke \"Alt-A\" is handled by Buttons that have a hot-letter \"A\" to activate the button. Regular Processing Unlike the hotkey processing, the regular processing is only sent to the currently focused view in the focus chain. The regular key processing is only invoked if no hotkey was caught. Cold-key Processing This stage only is executed if the focused view did not process the event, and is broadcast to all the views in the Toplevel. This method can be overwritten by views that want to provide accelerator functionality (Alt-key for example), but without interfering with normal ProcessKey behavior. Key Bindings Terminal.Gui supports rebinding keys. For example the default key for activating a button is Enter. You can change this using the ClearKeybinding and AddKeybinding methods: var btn = new Button (\"Press Me\"); btn.ClearKeybinding (Command.Accept); btn.AddKeyBinding (Key.b, Command.Accept); The Command enum lists generic operations that are implemented by views. For example Command.Accept in a Button results in the Clicked event firing while in TableView it is bound to CellActivated . Not all commands are implemented by all views (e.g. you cannot scroll in a Button). To see which commands are implemented by a View you can use the GetSupportedCommands() method. Not all controls have the same key bound for a given command, for example Command.Accept defaults to Key.Enter in a Button but defaults to Key.Space in RadioGroup . Global Key Handler Sometimes you may want to define global key handling logic for your entire application that is invoked regardless of what Window/View has focus. This can be achieved by using the Application.RootKeyEvent event." + "keywords": "Keyboard Event Processing Terminal.Gui respects common Linux, Mac, and Windows keyboard idioms. For example, clipboard operations use the familiar Control/Command-C, X, V model. CTRL-Q is used for exiting views (and apps). The input handling of Terminal.Gui is similar in some ways to Emacs and the Midnight Commander, so you can expect some of the special key combinations to be active. The key ESC can act as an Alt modifier (or Meta in Emacs parlance), to allow input on terminals that do not have an alt key. So to produce the sequence Alt-F , you can press either Alt-F , or ESC followed by the key F . To enter the key ESC , you can either press ESC and wait 100 milliseconds, or you can press ESC twice. ESC-0 , and ESC-1 through ESC-9 have a special meaning, they map to F10 , and F1 to F9 respectively. Apps can change key bindings using the AddKeyBinding API. Keyboard events are sent by the Main Loop to the Application class for processing. The keyboard events are sent exclusively to the current Toplevel , this being either the default that is created when you call Application.Init , or one that you created an passed to Application.Run(Toplevel) . Flow Keystrokes are first processes as hotkeys, then as regular keys, and there is a final cold post-processing event that is invoked if no view processed the key. HotKey Processing Events are first send to all views as a \"HotKey\", this means that the View.ProcessHotKey method is invoked on the current toplevel, which in turns propagates this to all the views in the hierarchy. If any view decides to process the event, no further processing takes place. This is how hotkeys for buttons are implemented. For example, the keystroke \"Alt-A\" is handled by Buttons that have a hot-letter \"A\" to activate the button. Regular Processing Unlike the hotkey processing, the regular processing is only sent to the currently focused view in the focus chain. The regular key processing is only invoked if no hotkey was caught. Cold-key Processing This stage only is executed if the focused view did not process the event, and is broadcast to all the views in the Toplevel. This method can be overwritten by views that want to provide accelerator functionality (Alt-key for example), but without interfering with normal ProcessKey behavior. Key Bindings Terminal.Gui supports rebinding keys. For example the default key for activating a button is Enter. You can change this using the ClearKeybinding and AddKeybinding methods: var btn = new Button (\"Press Me\"); btn.ClearKeybinding (Command.Accept); btn.AddKeyBinding (Key.b, Command.Accept); The Command enum lists generic operations that are implemented by views. For example Command.Accept in a Button results in the Clicked event firing while in TableView it is bound to CellActivated . Not all commands are implemented by all views (e.g. you cannot scroll in a Button). To see which commands are implemented by a View you can use the GetSupportedCommands() method. Not all controls have the same key bound for a given command, for example Command.Accept defaults to Key.Enter in a Button but defaults to Key.Space in RadioGroup . Global Key Handler Sometimes you may want to define global key handling logic for your entire application that is invoked regardless of what Window/View has focus. This can be achieved by using the Application.RootKeyEvent event." }, "articles/mainloop.html": { "href": "articles/mainloop.html", "title": "Event Processing and the Application Main Loop", - "keywords": "Event Processing and the Application Main Loop The method Application.Run that we covered before will wait for events from either the keyboard or mouse and route those events to the proper view. The job of waiting for events and dispatching them in the Application is implemented by an instance of the MainLoop class. Mainloops are a common idiom in many user interface toolkits so many of the concepts will be familiar to you if you have used other toolkits before. This class provides the following capabilities: Keyboard and mouse processing .NET Async support Timers processing Invoking of UI code from a background thread Idle processing handlers Possibility of integration with other mainloops. On Unix systems, it can monitor file descriptors for readability or writability. The MainLoop property in the the Application provides access to these functions. When your code invokes Application.Run (Toplevel) , the application will prepare the current Toplevel instance by redrawing the screen appropriately and then calling the mainloop to run. You can configure the Mainloop before calling Application.Run, or you can configure the MainLoop in response to events during the execution. The keyboard inputs is dispatched by the application class to the current TopLevel window this is covered in more detail in the Keyboard Event Processing document. Async Execution On startup, the Application class configured the .NET Asynchronous machinery to allow you to use the await keyword to run tasks in the background and have the execution of those tasks resume on the context of the main thread running the main loop. Once you invoke Application.Main the async machinery will be ready to use, and you can merely call methods using await from your main thread, and the awaited code will resume execution on the main thread. Timers Processing You can register timers to be executed at specified intervals by calling the AddTimeout method, like this: void UpdateTimer () { time.Text = DateTime.Now.ToString (); } var token = Application.MainLoop.AddTimeout (TimeSpan.FromSeconds (20), UpdateTimer); The return value from AddTimeout is a token value that you can use if you desire to cancel the timer before it runs: Application.MainLoop.RemoveTimeout (token); Idle Handlers You can register code to be executed when the application is idling and there are no events to process by calling the AddIdle method. This method takes as a parameter a function that will be invoked when the application is idling. Idle functions should return true if they should be invoked again, and false if the idle invocations should stop. Like the timer APIs, the return value is a token that can be used to cancel the scheduled idle function from being executed. Threading Like other UI toolkits, Terminal.Gui is generally not thread safe. You should avoid calling methods in the UI classes from a background thread as there is no guarantee that they will not corrupt the state of the UI application. Generally, as there is not much state, you will get lucky, but the application will not behave properly. You will be served better off by using C# async machinery and the various APIs in the System.Threading.Tasks.Task APIs. But if you absolutely must work with threads on your own you should only invoke APIs in Terminal.Gui from the main thread. To make this simple, you can use the Application.MainLoop.Invoke method and pass an Action . This action will be queued for execution on the main thread at an appropriate time and will run your code there. For example, the following shows how to properly update a label from a background thread: void BackgroundThreadUpdateProgress () { Application.MainLoop.Invoke (() => { progress.Text = $\"Progress: {bytesDownloaded/totalBytes}\"; }); } Integration With Other Main Loop Drivers It is possible to run the main loop in a way that it does not take over control of your application, but rather in a cooperative way. To do this, you must use the lower-level APIs in Application : the Begin method to prepare a toplevel for execution, followed by calls to MainLoop.EventsPending to determine whether the events must be processed, and in that case, calling RunLoop method and finally completing the process by calling End . The method Run is implemented like this: void Run (Toplevel top) { var runToken = Begin (view); RunLoop (runToken); End (runToken); } Unix File Descriptor Monitoring On Unix, it is possible to monitor file descriptors for input being available, or for the file descriptor being available for data to be written without blocking the application. To do this, you on Unix, you can cast the MainLoop instance to a UnixMainLoop and use the AddWatch method to register an interest on a particular condition." + "keywords": "Event Processing and the Application Main Loop See also Cross-platform Driver Model The method Application.Run that we covered before will wait for events from either the keyboard or mouse and route those events to the proper view. The job of waiting for events and dispatching them in the Application is implemented by an instance of the MainLoop class. Mainloops are a common idiom in many user interface toolkits so many of the concepts will be familiar to you if you have used other toolkits before. This class provides the following capabilities: Keyboard and mouse processing .NET Async support Timers processing Invoking of UI code from a background thread Idle processing handlers Possibility of integration with other mainloops. On Unix systems, it can monitor file descriptors for readability or writability. The MainLoop property in the the Application provides access to these functions. When your code invokes Application.Run (Toplevel) , the application will prepare the current Toplevel instance by redrawing the screen appropriately and then calling the mainloop to run. You can configure the Mainloop before calling Application.Run, or you can configure the MainLoop in response to events during the execution. The keyboard inputs is dispatched by the application class to the current TopLevel window this is covered in more detail in the Keyboard Event Processing document. Async Execution On startup, the Application class configured the .NET Asynchronous machinery to allow you to use the await keyword to run tasks in the background and have the execution of those tasks resume on the context of the main thread running the main loop. Once you invoke Application.Main the async machinery will be ready to use, and you can merely call methods using await from your main thread, and the awaited code will resume execution on the main thread. Timers Processing You can register timers to be executed at specified intervals by calling the AddTimeout method, like this: void UpdateTimer () { time.Text = DateTime.Now.ToString (); } var token = Application.MainLoop.AddTimeout (TimeSpan.FromSeconds (20), UpdateTimer); The return value from AddTimeout is a token value that you can use if you desire to cancel the timer before it runs: Application.MainLoop.RemoveTimeout (token); Idle Handlers You can register code to be executed when the application is idling and there are no events to process by calling the AddIdle method. This method takes as a parameter a function that will be invoked when the application is idling. Idle functions should return true if they should be invoked again, and false if the idle invocations should stop. Like the timer APIs, the return value is a token that can be used to cancel the scheduled idle function from being executed. Threading Like other UI toolkits, Terminal.Gui is generally not thread safe. You should avoid calling methods in the UI classes from a background thread as there is no guarantee that they will not corrupt the state of the UI application. Generally, as there is not much state, you will get lucky, but the application will not behave properly. You will be served better off by using C# async machinery and the various APIs in the System.Threading.Tasks.Task APIs. But if you absolutely must work with threads on your own you should only invoke APIs in Terminal.Gui from the main thread. To make this simple, you can use the Application.MainLoop.Invoke method and pass an Action . This action will be queued for execution on the main thread at an appropriate time and will run your code there. For example, the following shows how to properly update a label from a background thread: void BackgroundThreadUpdateProgress () { Application.MainLoop.Invoke (() => { progress.Text = $\"Progress: {bytesDownloaded/totalBytes}\"; }); } Integration With Other Main Loop Drivers It is possible to run the main loop in a way that it does not take over control of your application, but rather in a cooperative way. To do this, you must use the lower-level APIs in Application : the Begin method to prepare a toplevel for execution, followed by calls to MainLoop.EventsPending to determine whether the events must be processed, and in that case, calling RunLoop method and finally completing the process by calling End . The method Run is implemented like this: void Run (Toplevel top) { var runToken = Begin (view); RunLoop (runToken); End (runToken); } Unix File Descriptor Monitoring On Unix, it is possible to monitor file descriptors for input being available, or for the file descriptor being available for data to be written without blocking the application. To do this, you on Unix, you can cast the MainLoop instance to a UnixMainLoop and use the AddWatch method to register an interest on a particular condition." }, "articles/overview.html": { "href": "articles/overview.html", "title": "Terminal.Gui API Overview", - "keywords": "Terminal.Gui API Overview Terminal.Gui is a library intended to create console-based applications using C#. The framework has been designed to make it easy to write applications that will work on monochrome terminals, as well as modern color terminals with mouse support. This library works across Windows, Linux and MacOS. This library provides a text-based toolkit as works in a way similar to graphic toolkits. There are many controls that can be used to create your applications and it is event based, meaning that you create the user interface, hook up various events and then let the a processing loop run your application, and your code is invoked via one or more callbacks. The simplest application looks like this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var n = MessageBox.Query (50, 7, \"Question\", \"Do you like console apps?\", \"Yes\", \"No\"); Application.Shutdown (); return n; } } This example shows a prompt and returns an integer value depending on which value was selected by the user (Yes, No, or if they use chose not to make a decision and instead pressed the ESC key). More interesting user interfaces can be created by composing some of the various views that are included. In the following sections, you will see how applications are put together. In the example above, you can see that we have initialized the runtime by calling the Init method in the Application class - this sets up the environment, initializes the color schemes available for your application and clears the screen to start your application. The Application class, additionally creates an instance of the Toplevel class that is ready to be consumed, this instance is available in the Application.Top property, and can be used like this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var label = new Label (\"Hello World\") { X = Pos.Center (), Y = Pos.Center (), Height = 1, }; Application.Top.Add (label); Application.Run (); Application.Shutdown (); } } Typically, you will want your application to have more than a label, you might want a menu, and a region for your application to live in, the following code does this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem (\"_File\", new MenuItem [] { new MenuItem (\"_Quit\", \"\", () => { Application.RequestStop (); }) }), }); var win = new Window (\"Hello\") { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () - 1 }; // Add both menu and win in a single call Application.Top.Add (menu, win); Application.Run (); Application.Shutdown (); } } Views All visible elements on a Terminal.Gui application are implemented as Views . Views are self-contained objects that take care of displaying themselves, can receive keyboard and mouse input and participate in the focus mechanism. See the full list of Views provided by the Terminal.Gui library here . Every view can contain an arbitrary number of children views. These are called the Subviews. You can add a view to an existing view, by calling the Add method, for example, to add a couple of buttons to a UI, you can do this: void SetupMyView (View myView) { var label = new Label (\"Username: \") { X = 1, Y = 1, Width = 20, Height = 1 }; myView.Add (label); var username = new TextField (\"\") { X = 1, Y = 2, Width = 30, Height = 1 }; myView.Add (username); } The container of a given view is called the SuperView and it is a property of every View. Layout Terminal.Gui supports two different layout systems, absolute and computed \\ (controlled by the LayoutStyle property on the view. The absolute system is used when you want the view to be positioned exactly in one location and want to manually control where the view is. This is done by invoking your View constructor with an argument of type Rect . When you do this, to change the position of the View, you can change the Frame property on the View. The computed layout system offers a few additional capabilities, like automatic centering, expanding of dimensions and a handful of other features. To use this you construct your object without an initial Frame , but set the X , Y , Width and Height properties after the object has been created. Examples: // Dynamically computed var label = new Label (\"Hello\") { X = 1, Y = Pos.Center (), Width = Dim.Fill (), Height = 1 }; // Absolute position using the provided rectangle var label2 = new Label (new Rect (1, 2, 20, 1), \"World\") The computed layout system does not take integers, instead the X and Y properties are of type Pos and the Width and Height properties are of type Dim both which can be created implicitly from integer values. The Pos Type The Pos type on X and Y offers a few options: Absolute position, by passing an integer Percentage of the parent's view size - Pos.Percent(n) Anchored from the end of the dimension - AnchorEnd(int margin=0) Centered, using Center() Reference the Left (X), Top (Y), Bottom, Right positions of another view The Pos values can be added or subtracted, like this: // Set the X coordinate to 10 characters left from the center view.X = Pos.Center () - 10; view.Y = Pos.Percent (20); anotherView.X = AnchorEnd (10); anotherView.Width = 9; myView.X = Pos.X (view); myView.Y = Pos.Bottom (anotherView); The Dim Type The Dim type is used for the Width and Height properties on the View and offers the following options: Absolute size, by passing an integer Percentage of the parent's view size - Dim.Percent(n) Fill to the end - Dim.Fill () Reference the Width or Height of another view Like, Pos , objects of type Dim can be added an subtracted, like this: // Set the Width to be 10 characters less than filling // the remaining portion of the screen view.Width = Dim.Fill () - 10; view.Height = Dim.Percent(20) - 1; anotherView.Height = Dim.Height (view)+1 TopLevels, Windows and Dialogs. Among the many kinds of views, you typically will create a Toplevel view (or any of its subclasses, like Window or Dialog which is special kind of views that can be executed modally - that is, the view can take over all input and returns only when the user chooses to complete their work there. The following sections cover the differences. TopLevel Views Toplevel views have no visible user interface elements and occupy an arbitrary portion of the screen. You would use a toplevel Modal view for example to launch an entire new experience in your application, one where you would have a new top-level menu for example. You typically would add a Menu and a Window to your Toplevel, it would look like this: using Terminal.Gui; class Demo { static void Edit (string filename) { var top = new Toplevel () { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem (\"_File\", new MenuItem [] { new MenuItem (\"_Close\", \"\", () => { Application.RequestStop (); }) }), }); // nest a window for the editor var win = new Window (filename) { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () - 1 }; var editor = new TextView () { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; editor.Text = System.IO.File.ReadAllText (filename); win.Add (editor); // Add both menu and win in a single call top.Add (win, menu); Application.Run (top); Application.Shutdown (); } } Window Views Window views extend the Toplevel view by providing a frame and a title around the toplevel - and can be moved on the screen with the mouse (caveat: code is currently disabled) From a user interface perspective, you might have more than one Window on the screen at a given time. Dialogs Dialog are Window objects that happen to be centered in the middle of the screen. Dialogs are instances of a Window that are centered in the screen, and are intended to be used modally - that is, they run, and they are expected to return a result before resuming execution of your application. Dialogs are a subclass of Window and additionally expose the AddButton API which manages the layout of any button passed to it, ensuring that the buttons are at the bottom of the dialog. Example: bool okpressed = false; var ok = new Button(\"Ok\"); var cancel = new Button(\"Cancel\"); var dialog = new Dialog (\"Quit\", 60, 7, ok, cancel); Which will show something like this: +- Quit -----------------------------------------------+ | | | | | [ Ok ] [ Cancel ] | +------------------------------------------------------+ Running Modally To run your Dialog, Window or Toplevel modally, you will invoke the Application.Run method on the toplevel. It is up to your code and event handlers to invoke the Application.RequestStop() method to terminate the modal execution. bool okpressed = false; var ok = new Button(3, 14, \"Ok\") { Clicked = () => { Application.RequestStop (); okpressed = true; } }; var cancel = new Button(10, 14, \"Cancel\") { Clicked = () => Application.RequestStop () }; var dialog = new Dialog (\"Login\", 60, 18, ok, cancel); var entry = new TextField () { X = 1, Y = 1, Width = Dim.Fill (), Height = 1 }; dialog.Add (entry); Application.Run (dialog); if (okpressed) Console.WriteLine (\"The user entered: \" + entry.Text); There is no return value from running modally, so your code will need to have a mechanism of indicating the reason that the execution of the modal dialog was completed, in the case above, the okpressed value is set to true if the user pressed or selected the Ok button. Input Handling Every view has a focused view, and if that view has nested views, one of those is the focused view. This is called the focus chain, and at any given time, only one View has the focus. The library binds the key Tab to focus the next logical view, and the Shift-Tab combination to focus the previous logical view. Keyboard processing is divided in three stages: HotKey processing, regular processing and cold key processing. Hot key processing happens first, and it gives all the views in the current toplevel a chance to monitor whether the key needs to be treated specially. This for example handles the scenarios where the user pressed Alt-o, and a view with a highlighted \"o\" is being displayed. If no view processed the hotkey, then the key is sent to the currently focused view. If the key was not processed by the normal processing, all views are given a chance to process the keystroke in their cold processing stage. Examples include the processing of the \"return\" key in a dialog when a button in the dialog has been flagged as the \"default\" action. The most common case is the normal processing, which sends the keystrokes to the currently focused view. Mouse events are processed in visual order, and the event will be sent to the view on the screen. The only exception is that no mouse events are delivered to background views when a modal view is running. More details are available on the Keyboard Event Processing document. Colors and Color Schemes All views have been configured with a color scheme that will work both in color terminals as well as the more limited black and white terminals. The various styles are captured in the Colors class which defined color schemes for the toplevel, the normal views, the menu bar, popup dialog boxes and error dialog boxes, that you can use like this: Colors.Toplevel Colors.Base Colors.Menu Colors.Dialog Colors.Error You can use them for example like this to set the colors for a new Window: var w = new Window (\"Hello\"); w.ColorScheme = Colors.Error The ColorScheme represents four values, the color used for Normal text, the color used for normal text when a view is focused an the colors for the hot-keys both in focused and unfocused modes. By using ColorSchemes you ensure that your application will work correctbly both in color and black and white terminals. Some views support setting individual color attributes, you create an attribute for a particular pair of Foreground/Background like this: var myColor = Application.Driver.MakeAttribute (Color.Blue, Color.Red); var label = new Label (...); label.TextColor = myColor MainLoop, Threads and Input Handling Detailed description of the mainloop is described on the Event Processing and the Application Main Loop document." + "keywords": "Terminal.Gui API Overview Terminal.Gui is a library intended to create console-based applications using C#. The framework has been designed to make it easy to write applications that will work on monochrome terminals, as well as modern color terminals with mouse support. This library works across Windows, Linux and MacOS. This library provides a text-based toolkit as works in a way similar to graphic toolkits. There are many controls that can be used to create your applications and it is event based, meaning that you create the user interface, hook up various events and then let the a processing loop run your application, and your code is invoked via one or more callbacks. The simplest application looks like this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var n = MessageBox.Query (50, 7, \"Question\", \"Do you like console apps?\", \"Yes\", \"No\"); Application.Shutdown (); return n; } } This example shows a prompt and returns an integer value depending on which value was selected by the user (Yes, No, or if they use chose not to make a decision and instead pressed the ESC key). More interesting user interfaces can be created by composing some of the various views that are included. In the following sections, you will see how applications are put together. In the example above, you can see that we have initialized the runtime by calling the Init method in the Application class - this sets up the environment, initializes the color schemes available for your application and clears the screen to start your application. The Application class, additionally creates an instance of the Toplevel class that is ready to be consumed, this instance is available in the Application.Top property, and can be used like this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var label = new Label (\"Hello World\") { X = Pos.Center (), Y = Pos.Center (), Height = 1, }; Application.Top.Add (label); Application.Run (); Application.Shutdown (); } } Typically, you will want your application to have more than a label, you might want a menu, and a region for your application to live in, the following code does this: using Terminal.Gui; class Demo { static int Main () { Application.Init (); var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem (\"_File\", new MenuItem [] { new MenuItem (\"_Quit\", \"\", () => { Application.RequestStop (); }) }), }); var win = new Window (\"Hello\") { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () - 1 }; // Add both menu and win in a single call Application.Top.Add (menu, win); Application.Run (); Application.Shutdown (); } } Views All visible elements on a Terminal.Gui application are implemented as Views . Views are self-contained objects that take care of displaying themselves, can receive keyboard and mouse input and participate in the focus mechanism. See the full list of Views provided by the Terminal.Gui library here . Every view can contain an arbitrary number of children views. These are called the Subviews. You can add a view to an existing view, by calling the Add method, for example, to add a couple of buttons to a UI, you can do this: void SetupMyView (View myView) { var label = new Label (\"Username: \") { X = 1, Y = 1, Width = 20, Height = 1 }; myView.Add (label); var username = new TextField (\"\") { X = 1, Y = 2, Width = 30, Height = 1 }; myView.Add (username); } The container of a given view is called the SuperView and it is a property of every View. Layout Terminal.Gui supports two different layout systems, absolute and computed \\ (controlled by the LayoutStyle property on the view. The absolute system is used when you want the view to be positioned exactly in one location and want to manually control where the view is. This is done by invoking your View constructor with an argument of type Rect . When you do this, to change the position of the View, you can change the Frame property on the View. The computed layout system offers a few additional capabilities, like automatic centering, expanding of dimensions and a handful of other features. To use this you construct your object without an initial Frame , but set the X , Y , Width and Height properties after the object has been created. Examples: // Dynamically computed var label = new Label (\"Hello\") { X = 1, Y = Pos.Center (), Width = Dim.Fill (), Height = 1 }; // Absolute position using the provided rectangle var label2 = new Label (new Rect (1, 2, 20, 1), \"World\") The computed layout system does not take integers, instead the X and Y properties are of type Pos and the Width and Height properties are of type Dim both which can be created implicitly from integer values. The Pos Type The Pos type on X and Y offers a few options: Absolute position, by passing an integer Percentage of the parent's view size - Pos.Percent(n) Anchored from the end of the dimension - AnchorEnd(int margin=0) Centered, using Center() Reference the Left (X), Top (Y), Bottom, Right positions of another view The Pos values can be added or subtracted, like this: // Set the X coordinate to 10 characters left from the center view.X = Pos.Center () - 10; view.Y = Pos.Percent (20); anotherView.X = AnchorEnd (10); anotherView.Width = 9; myView.X = Pos.X (view); myView.Y = Pos.Bottom (anotherView); The Dim Type The Dim type is used for the Width and Height properties on the View and offers the following options: Absolute size, by passing an integer Percentage of the parent's view size - Dim.Percent(n) Fill to the end - Dim.Fill () Reference the Width or Height of another view Like, Pos , objects of type Dim can be added an subtracted, like this: // Set the Width to be 10 characters less than filling // the remaining portion of the screen view.Width = Dim.Fill () - 10; view.Height = Dim.Percent(20) - 1; anotherView.Height = Dim.Height (view)+1 TopLevels, Windows and Dialogs. Among the many kinds of views, you typically will create a Toplevel view (or any of its subclasses, like Window or Dialog which is special kind of views that can be executed modally - that is, the view can take over all input and returns only when the user chooses to complete their work there. The following sections cover the differences. TopLevel Views Toplevel views have no visible user interface elements and occupy an arbitrary portion of the screen. You would use a toplevel Modal view for example to launch an entire new experience in your application, one where you would have a new top-level menu for example. You typically would add a Menu and a Window to your Toplevel, it would look like this: using Terminal.Gui; class Demo { static void Edit (string filename) { var top = new Toplevel () { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; var menu = new MenuBar (new MenuBarItem [] { new MenuBarItem (\"_File\", new MenuItem [] { new MenuItem (\"_Close\", \"\", () => { Application.RequestStop (); }) }), }); // nest a window for the editor var win = new Window (filename) { X = 0, Y = 1, Width = Dim.Fill (), Height = Dim.Fill () - 1 }; var editor = new TextView () { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; editor.Text = System.IO.File.ReadAllText (filename); win.Add (editor); // Add both menu and win in a single call top.Add (win, menu); Application.Run (top); Application.Shutdown (); } } Window Views Window views extend the Toplevel view by providing a frame and a title around the toplevel - and can be moved on the screen with the mouse (caveat: code is currently disabled) From a user interface perspective, you might have more than one Window on the screen at a given time. Dialogs Dialog are Window objects that happen to be centered in the middle of the screen. Dialogs are instances of a Window that are centered in the screen, and are intended to be used modally - that is, they run, and they are expected to return a result before resuming execution of your application. Dialogs are a subclass of Window and additionally expose the AddButton API which manages the layout of any button passed to it, ensuring that the buttons are at the bottom of the dialog. Example: bool okpressed = false; var ok = new Button(\"Ok\"); var cancel = new Button(\"Cancel\"); var dialog = new Dialog (\"Quit\", 60, 7, ok, cancel); Which will show something like this: +- Quit -----------------------------------------------+ | | | | | [ Ok ] [ Cancel ] | +------------------------------------------------------+ Running Modally To run your Dialog, Window or Toplevel modally, you will invoke the Application.Run method on the toplevel. It is up to your code and event handlers to invoke the Application.RequestStop() method to terminate the modal execution. bool okpressed = false; var ok = new Button(3, 14, \"Ok\") { Clicked = () => { Application.RequestStop (); okpressed = true; } }; var cancel = new Button(10, 14, \"Cancel\") { Clicked = () => Application.RequestStop () }; var dialog = new Dialog (\"Login\", 60, 18, ok, cancel); var entry = new TextField () { X = 1, Y = 1, Width = Dim.Fill (), Height = 1 }; dialog.Add (entry); Application.Run (dialog); if (okpressed) Console.WriteLine (\"The user entered: \" + entry.Text); There is no return value from running modally, so your code will need to have a mechanism of indicating the reason that the execution of the modal dialog was completed, in the case above, the okpressed value is set to true if the user pressed or selected the Ok button. Input Handling Every view has a focused view, and if that view has nested views, one of those is the focused view. This is called the focus chain, and at any given time, only one View has the focus. The library binds the key Tab to focus the next logical view, and the Shift-Tab combination to focus the previous logical view. Keyboard processing is divided in three stages: HotKey processing, regular processing and cold key processing. Hot key processing happens first, and it gives all the views in the current toplevel a chance to monitor whether the key needs to be treated specially. This for example handles the scenarios where the user pressed Alt-o, and a view with a highlighted \"o\" is being displayed. If no view processed the hotkey, then the key is sent to the currently focused view. If the key was not processed by the normal processing, all views are given a chance to process the keystroke in their cold processing stage. Examples include the processing of the \"return\" key in a dialog when a button in the dialog has been flagged as the \"default\" action. The most common case is the normal processing, which sends the keystrokes to the currently focused view. Mouse events are processed in visual order, and the event will be sent to the view on the screen. The only exception is that no mouse events are delivered to background views when a modal view is running. More details are available on the Keyboard Event Processing document. Colors and Color Schemes All views have been configured with a color scheme that will work both in color terminals as well as the more limited black and white terminals. The various styles are captured in the Colors class which defined color schemes for the toplevel, the normal views, the menu bar, popup dialog boxes and error dialog boxes, that you can use like this: Colors.Toplevel Colors.Base Colors.Menu Colors.Dialog Colors.Error You can use them for example like this to set the colors for a new Window: var w = new Window (\"Hello\"); w.ColorScheme = Colors.Error The ColorScheme represents four values, the color used for Normal text, the color used for normal text when a view is focused an the colors for the hot-keys both in focused and unfocused modes. By using ColorSchemes you ensure that your application will work correctbly both in color and black and white terminals. Some views support setting individual color attributes, you create an attribute for a particular pair of Foreground/Background like this: var myColor = Application.Driver.MakeAttribute (Color.Blue, Color.Red); var label = new Label (...); label.TextColor = myColor MainLoop, Threads and Input Handling Detailed description of the mainloop is described on the Event Processing and the Application Main Loop document. Cross-Platform Drivers See Cross-platform Driver Model ." }, "articles/tableview.html": { "href": "articles/tableview.html", @@ -1302,7 +1307,7 @@ "index.html": { "href": "index.html", "title": "Terminal.Gui - Cross Platform Terminal UI toolkit for .NET", - "keywords": "Terminal.Gui - Cross Platform Terminal UI toolkit for .NET A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix. Terminal.Gui Project on GitHub Terminal.Gui API Documentation API Reference Views and controls built into the Terminal.Gui library Terminal.Gui API Overview Keyboard Event Processing Event Processing and the Application Main Loop TableView Deep Dive TreeView Deep Dive UI Catalog UI Catalog is a comprehensive sample library for Terminal.Gui. It provides a simple UI for adding to the catalog of scenarios. UI Catalog API Reference UI Catalog Source" + "keywords": "Terminal.Gui - Cross Platform Terminal UI toolkit for .NET A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix. Terminal.Gui Project on GitHub Terminal.Gui API Documentation API Reference Views and controls built into the Terminal.Gui library Terminal.Gui API Overview Keyboard Event Processing Event Processing and the Application Main Loop Cross-platform Driver Model TableView Deep Dive TreeView Deep Dive UI Catalog UI Catalog is a comprehensive sample library for Terminal.Gui. It provides a simple UI for adding to the catalog of scenarios. UI Catalog API Reference UI Catalog Source" }, "README.html": { "href": "README.html", diff --git a/docs/manifest.json b/docs/manifest.json index d6143212b..7d0811187 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -54,7 +54,7 @@ "output": { ".html": { "relative_path": "api/Terminal.Gui/Terminal.Gui.Application.html", - "hash": "dB8sk1W33oVLW3Y2+K7n4gQOe8vvp5yihmVbx/As47s=" + "hash": "p1SyGXNjGzQAuhjn2DhRYJh7DziWDgZjZFvLKCfyONI=" } }, "is_incremental": false, @@ -3084,13 +3084,25 @@ "is_incremental": false, "version": "" }, + { + "type": "Conceptual", + "source_relative_path": "articles/drivers.md", + "output": { + ".html": { + "relative_path": "articles/drivers.html", + "hash": "hqbYDRUiKz6fe2AMnkuPAPG4Fgc5tXHgFpGf8dS4hS4=" + } + }, + "is_incremental": false, + "version": "" + }, { "type": "Conceptual", "source_relative_path": "articles/index.md", "output": { ".html": { "relative_path": "articles/index.html", - "hash": "Alze7es8/SUCDYguOtrxYJRHqT4yZTexKObUT0Fku4I=" + "hash": "Gkp6XTz7lXblHMU6dupfr23WM45ZojbxfCVNqYB4onA=" } }, "is_incremental": false, @@ -3102,7 +3114,7 @@ "output": { ".html": { "relative_path": "articles/keyboard.html", - "hash": "cTqzspwxMVc9lBs9B0nXNGEZQzWoAWMw5DTDrcAF0DU=" + "hash": "oltPA2GzpORSe99P0GD6cgV3BSFlxJdSADSQC+GxFsc=" } }, "is_incremental": false, @@ -3114,7 +3126,7 @@ "output": { ".html": { "relative_path": "articles/mainloop.html", - "hash": "02RPG4/IAXYv3XE0Caa1OzOR35kDSmfYqn3h1SuId2c=" + "hash": "4izWB7lBl+y9C4J4re7tItVL7KCxG4QXavUW8tkFz5U=" } }, "is_incremental": false, @@ -3126,7 +3138,7 @@ "output": { ".html": { "relative_path": "articles/overview.html", - "hash": "iSNqKWz5HPqVAGi7+Osq1iP9GF/IV8d8VMeAH1BLkYQ=" + "hash": "t9sPzQPRgkY6YbBFareW+Ct0E6FvX6l44DPLHEtOveY=" } }, "is_incremental": false, @@ -3229,7 +3241,7 @@ "output": { ".html": { "relative_path": "index.html", - "hash": "+HOCH6J+OsNs8MmBBXWXXIeZt4JrROuNopRDioeOZGA=" + "hash": "2sQ2nqhnnNfYn1WPAJ5zMIStWFoTOWmzPttGd8TnJxM=" } }, "is_incremental": false, @@ -3252,17 +3264,17 @@ { "status": { "can_incremental": false, - "details": "Cannot build incrementally because config changed.", + "details": "Disable incremental build by force rebuild option.", "incrementalPhase": "build", "total_file_count": 0, "skipped_file_count": 0, - "full_build_reason_code": "ConfigChanged" + "full_build_reason_code": "ForceRebuild" }, "processors": { "ConceptualDocumentProcessor": { "can_incremental": false, "incrementalPhase": "build", - "total_file_count": 9, + "total_file_count": 10, "skipped_file_count": 0 }, "ManagedReferenceDocumentProcessor": { diff --git a/docs/styles/main.css b/docs/styles/main.css index 0d28db9c8..01bd6f07e 100644 --- a/docs/styles/main.css +++ b/docs/styles/main.css @@ -29,7 +29,7 @@ code,kbd,pre,samp{ button, a { - color: var(--highlight-dark); + color: var(--highlight-light); cursor: pointer; }