mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-29 17:28:01 +01:00
Merge branch 'fix_frame_dialog_messageboxes' into mondo_onlayoutcomplete_clip_msgboxdlg
This commit is contained in:
@@ -562,7 +562,7 @@ namespace Terminal.Gui {
|
||||
const char bottomChar = clearChar;
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Draws a frame for a window with padding aand n optional visible border inside the padding.
|
||||
/// Draws a frame for a window with padding and an optional visible border inside the padding.
|
||||
/// </summary>
|
||||
/// <param name="region">Screen relative region where the frame will be drawn.</param>
|
||||
/// <param name="paddingLeft">Number of columns to pad on the left (if 0 the border will not appear on the left).</param>
|
||||
@@ -724,7 +724,7 @@ namespace Terminal.Gui {
|
||||
// DrawFrame assumes the border is always at least one row/col thick
|
||||
// DrawWindowFrame assumes a padding of 0 means NO padding and no frame
|
||||
DrawWindowFrame (new Rect (region.X, region.Y, region.Width, region.Height),
|
||||
padding + 1, padding + 1, padding + 1, padding + 1, fill: fill);
|
||||
padding + 1, padding + 1, padding + 1, padding + 1, border: false, fill: fill);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -714,7 +714,7 @@ namespace Terminal.Gui {
|
||||
{
|
||||
var scrRect = ViewToScreen (region);
|
||||
var savedClip = ClipToBounds ();
|
||||
Driver.DrawFrame (scrRect, padding, fill);
|
||||
Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: fill);
|
||||
Driver.Clip = savedClip;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Terminal.Gui {
|
||||
// BUGBUG: Why do we draw the frame twice? This call is here to clear the content area, I think. Why not just clear that area?
|
||||
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
Driver.DrawFrame (scrRect, padding, true);
|
||||
Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: true);
|
||||
}
|
||||
|
||||
var savedClip = ClipToBounds ();
|
||||
@@ -173,7 +173,7 @@ namespace Terminal.Gui {
|
||||
|
||||
ClearNeedsDisplay ();
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
Driver.DrawFrame (scrRect, padding, false);
|
||||
Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: false);
|
||||
|
||||
if (HasFocus)
|
||||
Driver.SetAttribute (ColorScheme.HotNormal);
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
<AssemblyName>Terminal.Gui</AssemblyName>
|
||||
<DocumentationFile>bin\Release\Terminal.Gui.xml</DocumentationFile>
|
||||
<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
|
||||
<AssemblyVersion>0.82.0.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Release' ">true</GeneratePackageOnBuild>
|
||||
<PackageId>Terminal.Gui</PackageId>
|
||||
<PackageVersion>0.81</PackageVersion>
|
||||
<PackageVersion>0.82</PackageVersion>
|
||||
<Authors>Miguel de Icaza</Authors>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/migueldeicaza/gui.cs/</PackageProjectUrl>
|
||||
@@ -18,80 +19,141 @@
|
||||
<Owners>Miguel de Icaza</Owners>
|
||||
<Summary>Application framework for creating modern console applications using .NET </Summary>
|
||||
<Title>Gui.cs is a framework for creating console user interfaces</Title>
|
||||
<PackageReleaseNotes>0.81: Fix ncurses engine for macOS/Linux, it works again
|
||||
<PackageReleaseNotes>
|
||||
0.82: Many fixes
|
||||
* API documentation completely revamped and updated. Readme upated. Contributors guide added (Thanks @tig!)
|
||||
* New sample/demo app - UI Catalog - Replaces demo.cs with an easy to use and extend set of demo scenarios. (Thanks @tig!)
|
||||
* MenuBar can now have MenuItems directly (enables top-level menu items with no submenu). (Thanks @tig!)
|
||||
* Apps can now get KeyUp/KeyDown events. (Thanks @tig!)
|
||||
* Fixes #396 - Text alignnment issues. (Thanks @tig!)
|
||||
* Fixes #423 - Fix putting results of ocgv on command line erases cursor. (Thanks @tig!)
|
||||
* Example/Designer csproj files updated to latest Visual Studio model. (Thanks @tig!)
|
||||
* Adjusted the default colors for Windows to make more readable. (Thanks @tig!)
|
||||
* Toplevel.Ready event - Fired once the Toplevel's MainLoop has started (#445). (Thanks @tig!)
|
||||
* Refactored several events to use event vs. Action. (BREAKING CHANGE) (Thanks @tig!)
|
||||
* All compile warnings fixed. (Thanks @tig!)
|
||||
* Fixed a crash in EnsureVisibleBounds. (Thanks @tig!)
|
||||
* Application.Init/Shutdown are more robust. (Thanks @tig!)
|
||||
* New "Draw Window Frame" code; consistent across Window, FrameView, and Menu. Fixes many drawing bugs. (Thanks @tig!)
|
||||
* The project has been refactored an reorganized to reduce risk of bugs and make it easier to contribute #541. (Thanks @tig!)
|
||||
* Fixes #522 - Last view of Frameview not drawn. (Thanks @tig!)
|
||||
* Clipping has been fixed/restored - it now works properly. (#586) (Thanks @tig!)
|
||||
* Added a View.LayoutComplete event (#569). (Thanks @tig!)
|
||||
* Fixes #299 - MessageBox now auto sizes. (Thanks @tig!)
|
||||
* Fixes #557 - MessageBoxes on small screens. (Thanks @tig!)
|
||||
* Fixes #432 - MessageBox does not deal with long text; width/height params are goofy. (Thanks @tig!)
|
||||
* Fixes #35 - Dialog should have 1 char padding. (Thanks @tig!)
|
||||
* `MessageBox.Query` called with `width` and `height` == 0 get auto-size behavior. A new constructor is added making this easy to use. (Thanks @tig!)
|
||||
* Multi-line `MessageBox`es are now supported. Just use `\n` to add lines. The height of the MessageBox will adjust automatically. (Thanks @tig!)
|
||||
* The `MessageBoxes` Scenario in UI Catalog provides a full demo/test-case. (Thanks @tig!)
|
||||
* `Dialog` called with `width` and `height` == 0 are sized to 85% container. A new constructor is added making this easy to use. (Thanks @tig!)
|
||||
* Dialog (and MessageBox `Buttons` are now dynamically laid out using Computed layout. (Thanks @tig!)
|
||||
* A `Dialogs` Scenario has been added to UI Catalog making it easy to test the API. (Thanks @tig!)
|
||||
* `Button` now supports BOTH specifying a hotkey with '_' and the old behavior of using the first uppercase char (if '_' is not found). (Thanks @tig!)
|
||||
* All UI Catalog scenarios that use `Dialog` or `MessageBox` now use the simplified API. (Thanks @tig!)
|
||||
* `Terminal.Gui.dll` now has version metadata and UI Catalog's about box displays it as a test case. (Thanks @tig!)
|
||||
* Button, Dialog, and MessageBox API documentation has been updated/revised. (Thanks @tig!)
|
||||
* `View`, `Window`, `FrameView`, and `Dialog` have been upgraded to use the new `ConsoleDriver.DrawFrameWindow` API directly. (Thanks @tig!)
|
||||
* New ComboBox control (Thanks @fergusonr!)
|
||||
* ConsoleDriver now supports improved KeyModifers (shift keys) with an expanded Keys Sceanrio in UI Catalog. (Thanks @bdisp!)
|
||||
* Tons of mouse handling improvements. (Thanks @bdisp!)
|
||||
* Fsharp sample updated. (Thanks @bdisp!)
|
||||
* Fixes #562 - Background drawing issue. (Thanks @bdisp!)
|
||||
* Fixes #517 - Focus and mouse handlers enahced (BREAKING CHANGE). (Thanks @bdisp!)
|
||||
* Fixed resizing update and correct Toplevel colors without colors. (Thanks @bdisp!)
|
||||
* Fixed #515, #518, #536, #540. (Thanks @bdisp!)
|
||||
* Added Threading Scenario to UI catalog. (Thanks @bdisp!)
|
||||
* Added support for F11 and F12 keys. (Thanks @bdisp!)
|
||||
* Multiple improvements to Date/TimeField. (Thanks @bdisp!)
|
||||
* Fixes #409 - Invoke does not cause Wakeup #501. (Thanks @bdisp!)
|
||||
* Fixed Label text alignemnt. (Thanks @bdisp!)
|
||||
* Added mouse features in the Unix version. Supports xterm-1006. (Thanks @bdisp!)
|
||||
* Several StatusBar fixes. (Thanks @bdisp!)
|
||||
* Tons of mouse improvements including mouse wheel support (e.g. #404, #409). (Thanks @bdisp!)
|
||||
* Added a CloseFile method to the TextView as stated in #452. (Thanks @bdisp)
|
||||
* Added a OpenSelectedItem event to the ListView #429. (Thanks @bdisp!)
|
||||
* Fixes the return value of the position cursor in the TextField. (Thanks @bdisp!)
|
||||
* Updates screen on Unix window resizing. (Thanks @bdisp!)
|
||||
* Fixes the functions of the Edit->Copy-Cut-Paste menu for the TextField that was not working well. (Thanks @bdisp!)
|
||||
* More robust error handing in Pos/Dim. Fixes #355 stack overflow with Pos based on the size of windows at startup. Added a OnResized action to set the Pos after the terminal are resized. (Thanks @bdisp!)
|
||||
* Fixes #389 Window layouting breaks when resizing. (Thanks @bdisp!)
|
||||
* Fixes #557 MessageBox needs to take ustrings (BREAKING CHANGE). (Thanks @tig!)
|
||||
|
||||
* Fixes an issue with referencing views that have not been allocated yet causing a stack overflow
|
||||
* New OnCloseMenu event on menus
|
||||
* Button cursor position looks better
|
||||
* Listview in single-selection mode uses a radio-button look
|
||||
* Fixes a couple of crashes (356)
|
||||
* Default the samples to work on Catalina
|
||||
0.81:
|
||||
* Fix ncurses engine for macOS/Linux, it works again
|
||||
* Fixes an issue with referencing views that have not been allocated yet causing a stack overflow
|
||||
* New OnCloseMenu event on menus
|
||||
* Button cursor position looks better
|
||||
* Listview in single-selection mode uses a radio-button look
|
||||
* Fixes a couple of crashes (356)
|
||||
* Default the samples to work on Catalina
|
||||
|
||||
|
||||
0.80: Jumbo update from BDisp:
|
||||
0.80: Jumbo update from BDisp:
|
||||
|
||||
* Fixed key events traversal for modal dialogs
|
||||
* Fixes culture info of DataField from pr
|
||||
* Fixes the rectangle drawing issue
|
||||
* Redraw issue when setting coordinates of label
|
||||
* Added sub menus into menu bar with mouse and key navigation
|
||||
* Added Colors.Menu.Disabled to CursesDriver.cs
|
||||
* Mouse text selection with cut, copy and paste on text fields
|
||||
* Change sepChar from char to string in DateField
|
||||
* Adding a disabled menu item in the demo file
|
||||
* Fixes Button repainting issue when changing the text length to one smaller
|
||||
* Fixes Redraw issue when setting coordinates of label
|
||||
* Fixes ScrollView does not render some content
|
||||
* Fixed bug in Button that caused a loop redraw calling TerminalResized
|
||||
* Fixes a repaint issue (282)
|
||||
* Mouse features added to FileDialog including wheel support.
|
||||
* Switch netcoreapp target to netstandard2.0
|
||||
* Added TextView.TextChanged event
|
||||
* Fixes issue #306 async/await hang (#312)
|
||||
* Replaced static driver initialization with property getter for reference passing in Core.cs::View class, this allows the library to be reinitialized at any time.
|
||||
* Made the Shutdown method on Core.cs::Application class public, since there is no reason to keep it private. Applications can shutdown the library and revert the console to the initial stage by calling it.
|
||||
* Fixed a memory-leak on Drivers/WindowsDriver class by destroying the generated screen buffers at library shutdown by calling CloseHandle.
|
||||
* Minor change to Core.cs::Application.Init(Func) for better initialization status tracking, via backend property instead of relying on the Top field.
|
||||
* Moved `ListView.ListWrapper` out of `ListView` migueldeicaza/gui.cs#313` (#315)
|
||||
* Resizing the MessageBox width to accommodate all message text (#299)
|
||||
* Timefield format with bounds values (#303)
|
||||
* Implemented lower and upper bounds to TimeField
|
||||
* Passing old text to the Changed event handler
|
||||
* Extract methods on ListView to make it controlable from other controls
|
||||
* Fixed key events traversal for modal dialogs
|
||||
* Fixes culture info of DataField from pr
|
||||
* Fixes the rectangle drawing issue
|
||||
* Redraw issue when setting coordinates of label
|
||||
* Added sub menus into menu bar with mouse and key navigation
|
||||
* Added Colors.Menu.Disabled to CursesDriver.cs
|
||||
* Mouse text selection with cut, copy and paste on text fields
|
||||
* Change sepChar from char to string in DateField
|
||||
* Adding a disabled menu item in the demo file
|
||||
* Fixes Button repainting issue when changing the text length to one smaller
|
||||
* Fixes Redraw issue when setting coordinates of label
|
||||
* Fixes ScrollView does not render some content
|
||||
* Fixed bug in Button that caused a loop redraw calling TerminalResized
|
||||
* Fixes a repaint issue (282)
|
||||
* Mouse features added to FileDialog including wheel support.
|
||||
* Switch netcoreapp target to netstandard2.0
|
||||
* Added TextView.TextChanged event
|
||||
* Fixes issue #306 async/await hang (#312)
|
||||
* Replaced static driver initialization with property getter for reference passing in Core.cs::View class, this allows the library to be reinitialized at any time.
|
||||
* Made the Shutdown method on Core.cs::Application class public, since there is no reason to keep it private. Applications can shutdown the library and revert the console to the initial stage by calling it.
|
||||
* Fixed a memory-leak on Drivers/WindowsDriver class by destroying the generated screen buffers at library shutdown by calling CloseHandle.
|
||||
* Minor change to Core.cs::Application.Init(Func) for better initialization status tracking, via backend property instead of relying on the Top field.
|
||||
* Moved `ListView.ListWrapper` out of `ListView` migueldeicaza/gui.cs#313` (#315)
|
||||
* Resizing the MessageBox width to accommodate all message text (#299)
|
||||
* Timefield format with bounds values (#303)
|
||||
* Implemented lower and upper bounds to TimeField
|
||||
* Passing old text to the Changed event handler
|
||||
* Extract methods on ListView to make it controlable from other controls
|
||||
|
||||
0.70: Bug fixes (320, 321, 306, 304, 291, 299, 303); Surface ListView.ListWrapper, surface various internal methods for use in ListView; Allow list item selection; ; 0.65: Added new TimeField from Jörg Preiß; Fixes for Backtab by Martin Björkström; ListView now supports simple selection; Bug fixes by giladlevi, Daniel Cazzulino and Marius Ungureanu; New Application.Run of T entry point by Daniel Cazzulino; Added various View methods to bring forward, backwards and move views in the hierarchy; Switch to Portable PDBs by Daniel Cazzulino; Dims can now be compared by Daniel Cazzulino; OnMenuOpen handler by giladlevi; Various memory usage optimizations by giladlevi; FileDialog.FilePath is now a full path by Yanwei Wang; ISupportInitialize/ISupportInitializeNotification is now supported thanks to the work from Daniel Cazzulino; Support for non-modal TopLevels by Daniel Cazzulino and Adrian Alonso; 0.24: the Windows driver implements WakeUp, allowing some scenarios like bug #207 to be fixed;
|
||||
0.23: Better support for disabled menu items; Raises text changed event after the internals have been updated; Fix Caps-NumLock; Alt-HotKey now work on menus
|
||||
0.22: Correct vertical scrollview behavior, Small curses driver fix for terminals without mouse support, TextView support for scrolling, Surface Used property on TextField, Surface Cursor on RadioGroup.
|
||||
0.70: Bug fixes (320, 321, 306, 304, 291, 299, 303); Surface ListView.ListWrapper, surface various internal methods for use in ListView; Allow list item selection; ; 0.65: Added new TimeField from Jörg Preiß; Fixes for Backtab by Martin Björkström; ListView now supports simple selection; Bug fixes by giladlevi, Daniel Cazzulino and Marius Ungureanu; New Application.Run of T entry point by Daniel Cazzulino; Added various View methods to bring forward, backwards and move views in the hierarchy; Switch to Portable PDBs by Daniel Cazzulino; Dims can now be compared by Daniel Cazzulino; OnMenuOpen handler by giladlevi; Various memory usage optimizations by giladlevi; FileDialog.FilePath is now a full path by Yanwei Wang; ISupportInitialize/ISupportInitializeNotification is now supported thanks to the work from Daniel Cazzulino; Support for non-modal TopLevels by Daniel Cazzulino and Adrian Alonso; 0.24: the Windows driver implements WakeUp, allowing some scenarios like bug #207 to be fixed;
|
||||
0.23: Better support for disabled menu items; Raises text changed event after the internals have been updated; Fix Caps-NumLock; Alt-HotKey now work on menus
|
||||
0.22: Correct vertical scrollview behavior, Small curses driver fix for terminals without mouse support, TextView support for scrolling, Surface Used property on TextField, Surface Cursor on RadioGroup.
|
||||
|
||||
0.21: Introudce Attribute.Make to more easily create attributes, and fix a bug in the file panel.
|
||||
0.20: Expose some of the CursesDriver APIs
|
||||
0.19: PageUpDown updates (GaikwadPratik); Fixes in multi-line labels (hlfrye@gmail.com); Support Delete char in TextView (Greg Amidon); Prevent empty TextViews from crashing; Allow TextFields to be updated on the Changed event.
|
||||
0.18: Fixes hotkeys for menus (Sang Kil); Fixes RemoveAll for all containers; Allows Toplevels with no views; Fixes FileDialog layout; Prevent crash in TextView
|
||||
0.17: Unix, dynamically load ncurses library to support different configurations, and not require -dev on Linux, various bug fixes.
|
||||
0.21: Introudce Attribute.Make to more easily create attributes, and fix a bug in the file panel.
|
||||
0.20: Expose some of the CursesDriver APIs
|
||||
0.19: PageUpDown updates (GaikwadPratik); Fixes in multi-line labels (hlfrye@gmail.com); Support Delete char in TextView (Greg Amidon); Prevent empty TextViews from crashing; Allow TextFields to be updated on the Changed event.
|
||||
0.18: Fixes hotkeys for menus (Sang Kil); Fixes RemoveAll for all containers; Allows Toplevels with no views; Fixes FileDialog layout; Prevent crash in TextView
|
||||
0.17: Unix, dynamically load ncurses library to support different configurations, and not require -dev on Linux, various bug fixes.
|
||||
|
||||
0.16: Support for Shift-Tab on Windows (fix by @mholo65)
|
||||
0.16: Support for Shift-Tab on Windows (fix by @mholo65)
|
||||
|
||||
0.15: WindowsDriver fix for Legacy Console keyboard input (issue #105)
|
||||
0.15: WindowsDriver fix for Legacy Console keyboard input (issue #105)
|
||||
|
||||
0.14: WindowsDriver fix for EventType size.
|
||||
0.14: WindowsDriver fix for EventType size.
|
||||
|
||||
0.13: Fixes keyboard input for Alt-Gr and numbers.
|
||||
0.13: Fixes keyboard input for Alt-Gr and numbers.
|
||||
|
||||
0.12: Fixes the text editor merge line command.
|
||||
0.12: Fixes the text editor merge line command.
|
||||
|
||||
0.11: Simplify TextField implementation, fixes a couple of editing bugs.
|
||||
0.11: Simplify TextField implementation, fixes a couple of editing bugs.
|
||||
|
||||
0.10: Fix unicode rendering for TextField, and bring F# example
|
||||
0.10: Fix unicode rendering for TextField, and bring F# example
|
||||
|
||||
0.9: File Open/File Save dialogs, HexView, Windows Driver allows resizing, mouse events, faster (thanks to Nick Van Dyck, nickvdyck for the contribution!), smaller bug fixes,
|
||||
0.9: File Open/File Save dialogs, HexView, Windows Driver allows resizing, mouse events, faster (thanks to Nick Van Dyck, nickvdyck for the contribution!), smaller bug fixes,
|
||||
|
||||
0.8: Completes keyboard support on Windows; Fixes delete on Windows, some layout fixes.
|
||||
0.7: terminal resizing on Linux propagates sizes with new layout system, and new features on the layout system (documented)
|
||||
0.6: new layout system, multi-line textview editor, Linux bug fix for .NET Core
|
||||
0.5: support Linux with .NET Core, Windows driver fixes.
|
||||
0.4: hotkey handling fix for RadioButtons
|
||||
0.3: Fix Windows key input to not echo characters on console, proper Fkey mapping
|
||||
0.2: Auto-detect the best console</PackageReleaseNotes>
|
||||
0.8: Completes keyboard support on Windows; Fixes delete on Windows, some layout fixes.
|
||||
0.7: terminal resizing on Linux propagates sizes with new layout system, and new features on the layout system (documented)
|
||||
0.6: new layout system, multi-line textview editor, Linux bug fix for .NET Core
|
||||
0.5: support Linux with .NET Core, Windows driver fixes.
|
||||
0.4: hotkey handling fix for RadioButtons
|
||||
0.3: Fix Windows key input to not echo characters on console, proper Fkey mapping
|
||||
0.2: Auto-detect the best console
|
||||
</PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
|
||||
@@ -55,29 +55,32 @@ namespace Terminal.Gui {
|
||||
public Action Clicked;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="Button"/> based on the given text at position 0,0
|
||||
/// Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The size of the <see cref="Button"/> is computed based on the
|
||||
/// text length.
|
||||
/// The width of the <see cref="Button"/> is computed based on the
|
||||
/// text length. The height will always be 1.
|
||||
/// </remarks>
|
||||
/// <param name="text">The button's text</param>
|
||||
/// <param name="is_default">If set, this makes the button the default button in the current view. <seealso cref="IsDefault"/></param>
|
||||
/// <param name="is_default">
|
||||
/// If <c>true</c>, a special decoration is used, and the user pressing the enter key
|
||||
/// in a <see cref="Dialog"/> will implicitly activate this button.
|
||||
/// </param>
|
||||
public Button (ustring text, bool is_default = false) : base ()
|
||||
{
|
||||
CanFocus = true;
|
||||
Text = text ?? string.Empty;
|
||||
this.IsDefault = is_default;
|
||||
int w = SetWidthHeight (text, is_default);
|
||||
Frame = new Rect (0, 0, w, 1);
|
||||
Frame = new Rect (Frame.Location, new Size (w, 1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="Button"/> at the given coordinates, based on the given text
|
||||
/// Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Absolute"/> layout, based on the given text
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The size of the <see cref="Button"/> is computed based on the
|
||||
/// text length.
|
||||
/// The width of the <see cref="Button"/> is computed based on the
|
||||
/// text length. The height will always be 1.
|
||||
/// </remarks>
|
||||
/// <param name="x">X position where the button will be shown.</param>
|
||||
/// <param name="y">Y position where the button will be shown.</param>
|
||||
@@ -85,17 +88,19 @@ namespace Terminal.Gui {
|
||||
public Button (int x, int y, ustring text) : this (x, y, text, false) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="Button"/> at the given coordinates, based on the given text, and with the specified <see cref="IsDefault"/> value
|
||||
/// Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Absolute"/> layout, based on the given text.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the value for is_default is true, a special
|
||||
/// decoration is used, and the enter key on a
|
||||
/// dialog would implicitly activate this button.
|
||||
/// The width of the <see cref="Button"/> is computed based on the
|
||||
/// text length. The height will always be 1.
|
||||
/// </remarks>
|
||||
/// <param name="x">X position where the button will be shown.</param>
|
||||
/// <param name="y">Y position where the button will be shown.</param>
|
||||
/// <param name="text">The button's text</param>
|
||||
/// <param name="is_default">If set, this makes the button the default button in the current view, which means that if the user presses return on a view that does not handle return, it will be treated as if he had clicked on the button</param>
|
||||
/// <param name="is_default">
|
||||
/// If <c>true</c>, a special decoration is used, and the user pressing the enter key
|
||||
/// in a <see cref="Dialog"/> will implicitly activate this button.
|
||||
/// </param>
|
||||
public Button (int x, int y, ustring text, bool is_default)
|
||||
: base (new Rect (x, y, text.Length + 4 + (is_default ? 2 : 0), 1))
|
||||
{
|
||||
@@ -110,6 +115,7 @@ namespace Terminal.Gui {
|
||||
int w = text.Length + 4 + (is_default ? 2 : 0);
|
||||
Width = w;
|
||||
Height = 1;
|
||||
Frame = new Rect (Frame.Location, new Size (w, 1));
|
||||
return w;
|
||||
}
|
||||
|
||||
@@ -137,17 +143,27 @@ namespace Terminal.Gui {
|
||||
else
|
||||
shown_text = "[ " + text + " ]";
|
||||
|
||||
hot_pos = -1;
|
||||
hot_key = (Rune)0;
|
||||
int i = 0;
|
||||
foreach (Rune c in shown_text) {
|
||||
if (Rune.IsUpper (c)) {
|
||||
hot_key = c;
|
||||
hot_pos = i;
|
||||
break;
|
||||
hot_pos = shown_text.IndexOf ('_');
|
||||
|
||||
if (hot_pos == -1) {
|
||||
// Use first upper-case char
|
||||
int i = 0;
|
||||
foreach (Rune c in shown_text) {
|
||||
if (Rune.IsUpper (c)) {
|
||||
hot_key = c;
|
||||
hot_pos = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
// Use char after '_'
|
||||
var start = shown_text [0, hot_pos];
|
||||
shown_text = start + shown_text [hot_pos + 1, shown_text.Length];
|
||||
hot_key = Char.ToUpper((char)shown_text [hot_pos]);
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
|
||||
@@ -214,7 +230,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
///<inheritdoc cref="MouseEvent"/>
|
||||
public override bool MouseEvent(MouseEvent me)
|
||||
public override bool MouseEvent (MouseEvent me)
|
||||
{
|
||||
if (me.Flags == MouseFlags.Button1Clicked) {
|
||||
SuperView.SetFocus (this);
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace Terminal.Gui {
|
||||
|
||||
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
Driver.DrawFrame (scrRect, padding, true);
|
||||
Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: true);
|
||||
}
|
||||
|
||||
var savedClip = ClipToBounds ();
|
||||
@@ -149,7 +149,7 @@ namespace Terminal.Gui {
|
||||
|
||||
ClearNeedsDisplay ();
|
||||
Driver.SetAttribute (ColorScheme.Normal);
|
||||
Driver.DrawFrame (scrRect, padding, false);
|
||||
Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: false);
|
||||
|
||||
if (HasFocus)
|
||||
Driver.SetAttribute (ColorScheme.HotNormal);
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
// Authors:
|
||||
// Miguel de Icaza (miguel@gnome.org)
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NStack;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// The <see cref="Dialog"/> <see cref="View"/> is a <see cref="Window"/> that by default is centered and contains one
|
||||
/// or more <see cref="Button"/>. It defaults to the <see cref="Colors.Dialog"/> color scheme and has a 1 cell padding around the edges.
|
||||
/// or more <see cref="Button"/>s. It defaults to the <see cref="Colors.Dialog"/> color scheme and has a 1 cell padding around the edges.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To run the <see cref="Dialog"/> modally, create the <see cref="Dialog"/>, and pass it to <see cref="Application.Run()"/>.
|
||||
@@ -21,21 +21,37 @@ namespace Terminal.Gui {
|
||||
/// </remarks>
|
||||
public class Dialog : Window {
|
||||
List<Button> buttons = new List<Button> ();
|
||||
const int padding = 1;
|
||||
const int padding = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Dialog"/> class with an optional set of <see cref="Button"/>s to display
|
||||
/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Absolute"/> positioning
|
||||
/// and an optional set of <see cref="Button"/>s to display
|
||||
/// </summary>
|
||||
/// <param name="title">Title for the dialog.</param>
|
||||
/// <param name="width">Width for the dialog.</param>
|
||||
/// <param name="height">Height for the dialog.</param>
|
||||
/// <param name="buttons">Optional buttons to lay out at the bottom of the dialog.</param>
|
||||
/// <remarks>
|
||||
/// if <c>width</c> and <c>height</c> are both 0, the Dialog will be vertically and horizontally centered in the
|
||||
/// container and the size will be 85% of the container.
|
||||
/// After initialzation use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> to override this with a location or size.
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// Use the constructor that does not take a <c>width</c> and <c>height</c> instead.
|
||||
/// </remarks>
|
||||
public Dialog (ustring title, int width, int height, params Button [] buttons) : base (title, padding: padding)
|
||||
{
|
||||
X = Pos.Center ();
|
||||
Y = Pos.Center ();
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
if (width == 0 & height == 0) {
|
||||
Width = Dim.Percent (85);
|
||||
Height = Dim.Percent (85);
|
||||
} else {
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
ColorScheme = Colors.Dialog;
|
||||
Modal = true;
|
||||
|
||||
@@ -47,6 +63,20 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Dialog"/> class using <see cref="LayoutStyle.Computed"/> positioning
|
||||
/// and with an optional set of <see cref="Button"/>s to display
|
||||
/// </summary>
|
||||
/// <param name="title">Title for the dialog.</param>
|
||||
/// <param name="buttons">Optional buttons to lay out at the bottom of the dialog.</param>
|
||||
/// <remarks>
|
||||
/// if <c>width</c> and <c>height</c> are both 0, the Dialog will be vertically and horizontally centered in the
|
||||
/// container and the size will be 85% of the container.
|
||||
/// After initialzation use <c>X</c>, <c>Y</c>, <c>Width</c>, and <c>Height</c> to override this with a location or size.
|
||||
/// </remarks>
|
||||
public Dialog (ustring title, params Button [] buttons) : this (title: title, width: 0, height: 0, buttons: buttons) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="Button"/> to the <see cref="Dialog"/>, its layout will be controled by the <see cref="Dialog"/>
|
||||
/// </summary>
|
||||
@@ -58,31 +88,31 @@ namespace Terminal.Gui {
|
||||
|
||||
buttons.Add (button);
|
||||
Add (button);
|
||||
LayoutSubviews ();
|
||||
}
|
||||
|
||||
internal int GetButtonsWidth ()
|
||||
{
|
||||
if (buttons.Count == 0) {
|
||||
return 0;
|
||||
}
|
||||
return buttons.Select (b => b.Bounds.Width).Sum () + buttons.Count() - 1;
|
||||
}
|
||||
|
||||
///<inheritdoc cref="LayoutSubviews"/>
|
||||
public override void LayoutSubviews ()
|
||||
{
|
||||
int buttonsWidth = GetButtonsWidth ();
|
||||
|
||||
int shiftLeft = Math.Max((Bounds.Width - buttonsWidth) / 2 - 2, 0);
|
||||
for (int i = buttons.Count - 1; i >= 0 ; i--) {
|
||||
Button button = buttons [i];
|
||||
shiftLeft += button.Frame.Width + 1;
|
||||
button.X = Pos.AnchorEnd (shiftLeft);
|
||||
button.Y = Pos.AnchorEnd (1);
|
||||
}
|
||||
|
||||
base.LayoutSubviews ();
|
||||
|
||||
int buttonSpace = 0;
|
||||
int maxHeight = 0;
|
||||
|
||||
foreach (var b in buttons) {
|
||||
buttonSpace += b.Frame.Width + 1;
|
||||
maxHeight = Math.Max (maxHeight, b.Frame.Height);
|
||||
}
|
||||
const int borderWidth = 2;
|
||||
var start = (Frame.Width-borderWidth - buttonSpace) / 2;
|
||||
|
||||
var y = Frame.Height - borderWidth - maxHeight-1-padding;
|
||||
foreach (var b in buttons) {
|
||||
var bf = b.Frame;
|
||||
|
||||
b.Frame = new Rect (start, y, bf.Width, bf.Height);
|
||||
|
||||
start += bf.Width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
///<inheritdoc cref="ProcessKey"/>
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
using System;
|
||||
using NStack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// MessageBox displays a modal message to the user, with a title, a message and a series of options that the user can choose from.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// The difference between the <see cref="Query"/> and <see cref="ErrorQuery"/> method is the default set of colors used for the message box.
|
||||
/// The difference between the <see cref="Query(ustring, ustring, ustring[])"/> and <see cref="ErrorQuery(ustring, ustring, ustring[])"/>
|
||||
/// method is the default set of colors used for the message box.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The following example pops up a <see cref="MessageBox"/> with 50 columns, and 7 lines, with the specified title and text, plus two <see cref="Button"/>s.
|
||||
/// The following example pops up a <see cref="MessageBox"/> with the specified title and text, plus two <see cref="Button"/>s.
|
||||
/// The value -1 is returned when the user cancels the <see cref="MessageBox"/> by pressing the ESC key.
|
||||
/// </para>
|
||||
/// <example>
|
||||
/// <code lang="c#">
|
||||
/// var n = MessageBox.Query (50, 7, "Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No");
|
||||
/// var n = MessageBox.Query ("Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No");
|
||||
/// if (n == 0)
|
||||
/// quit = true;
|
||||
/// else
|
||||
@@ -29,11 +34,30 @@ namespace Terminal.Gui {
|
||||
/// <param name="title">Title for the query.</param>
|
||||
/// <param name="message">Message to display, might contain multiple lines..</param>
|
||||
/// <param name="buttons">Array of buttons to add.</param>
|
||||
public static int Query (int width, int height, string title, string message, params string [] buttons)
|
||||
/// <remarks>
|
||||
/// Use <see cref="Query(ustring, ustring, ustring[])"/> instead; it automatically sizes the MessageBox based on the contents.
|
||||
/// </remarks>
|
||||
public static int Query (int width, int height, ustring title, ustring message, params ustring [] buttons)
|
||||
{
|
||||
return QueryFull (false, width, height, title, message, buttons);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Presents an error <see cref="MessageBox"/> with the specified title and message and a list of buttons to show to the user.
|
||||
/// </summary>
|
||||
/// <returns>The index of the selected button, or -1 if the user pressed ESC to close the dialog.</returns>
|
||||
/// <param name="title">Title for the query.</param>
|
||||
/// <param name="message">Message to display, might contain multiple lines.</param>
|
||||
/// <param name="buttons">Array of buttons to add.</param>
|
||||
/// <remarks>
|
||||
/// The message box will be vertically and horizontally centered in the container and the size will be automatically determined
|
||||
/// from the size of the message and buttons.
|
||||
/// </remarks>
|
||||
public static int Query (ustring title, ustring message, params ustring [] buttons)
|
||||
{
|
||||
return QueryFull (false, 0, 0, title, message, buttons);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Presents an error <see cref="MessageBox"/> with the specified title and message and a list of buttons to show to the user.
|
||||
/// </summary>
|
||||
@@ -43,34 +67,91 @@ namespace Terminal.Gui {
|
||||
/// <param name="title">Title for the query.</param>
|
||||
/// <param name="message">Message to display, might contain multiple lines.</param>
|
||||
/// <param name="buttons">Array of buttons to add.</param>
|
||||
public static int ErrorQuery (int width, int height, string title, string message, params string [] buttons)
|
||||
/// <remarks>
|
||||
/// Use <see cref="ErrorQuery(ustring, ustring, ustring[])"/> instead; it automatically sizes the MessageBox based on the contents.
|
||||
/// </remarks>
|
||||
public static int ErrorQuery (int width, int height, ustring title, ustring message, params ustring [] buttons)
|
||||
{
|
||||
return QueryFull (true, width, height, title, message, buttons);
|
||||
}
|
||||
|
||||
static int QueryFull (bool useErrorColors, int width, int height, string title, string message, params string [] buttons)
|
||||
/// <summary>
|
||||
/// Presents an error <see cref="MessageBox"/> with the specified title and message and a list of buttons to show to the user.
|
||||
/// </summary>
|
||||
/// <returns>The index of the selected button, or -1 if the user pressed ESC to close the dialog.</returns>
|
||||
/// <param name="title">Title for the query.</param>
|
||||
/// <param name="message">Message to display, might contain multiple lines.</param>
|
||||
/// <param name="buttons">Array of buttons to add.</param>
|
||||
/// <remarks>
|
||||
/// The message box will be vertically and horizontally centered in the container and the size will be automatically determined
|
||||
/// from the size of the title, message. and buttons.
|
||||
/// </remarks>
|
||||
public static int ErrorQuery (ustring title, ustring message, params ustring [] buttons)
|
||||
{
|
||||
return QueryFull (true, 0, 0, title, message, buttons);
|
||||
}
|
||||
|
||||
|
||||
static int QueryFull (bool useErrorColors, int width, int height, ustring title, ustring message, params ustring [] buttons)
|
||||
{
|
||||
const int defaultWidth = 30;
|
||||
int textWidth = Label.MaxWidth (message, width);
|
||||
int clicked = -1, count = 0;
|
||||
|
||||
var d = new Dialog (title, Math.Max(width, textWidth) + 4, height);
|
||||
if (useErrorColors)
|
||||
d.ColorScheme = Colors.Error;
|
||||
int textHeight = message.Count(ustring.Make('\n')) + 1;
|
||||
int msgboxHeight = Math.Max (1, textHeight) + 4; // textHeight + (top + top padding + buttons + bottom)
|
||||
|
||||
// Create button array for Dialog
|
||||
int count = 0;
|
||||
List<Button> buttonList = new List<Button> ();
|
||||
foreach (var s in buttons) {
|
||||
int n = count++;
|
||||
var b = new Button (s);
|
||||
b.Clicked += delegate {
|
||||
clicked = n;
|
||||
d.Running = false;
|
||||
};
|
||||
d.AddButton (b);
|
||||
if (count == 0) {
|
||||
b.IsDefault = true;
|
||||
}
|
||||
buttonList.Add (b);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Create Dialog (retain backwards compat by supporting specifying height/width)
|
||||
Dialog d;
|
||||
if (width == 0 & height == 0) {
|
||||
d = new Dialog (title, buttonList.ToArray ());
|
||||
d.Height = msgboxHeight;
|
||||
} else {
|
||||
d = new Dialog (title, Math.Max (width, textWidth) + 4, height, buttonList.ToArray ());
|
||||
}
|
||||
|
||||
if (useErrorColors) {
|
||||
d.ColorScheme = Colors.Error;
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
var l = new Label (textWidth > width ? 0 : (width - 4 - textWidth) / 2, 0, message);
|
||||
var l = new Label (textWidth > width ? 0 : (width - 4 - textWidth) / 2, 1, message);
|
||||
//l.ColorScheme = Colors.Menu;
|
||||
if (true) { //width == 0 & height == 0) {
|
||||
l.LayoutStyle = LayoutStyle.Computed;
|
||||
l.TextAlignment = TextAlignment.Centered;
|
||||
l.X = Pos.Center ();
|
||||
l.Y = Pos.Center ();
|
||||
l.Width = Dim.Fill (2);
|
||||
l.Height = Dim.Fill (2);
|
||||
}
|
||||
d.Add (l);
|
||||
}
|
||||
|
||||
// Dynamically size Width
|
||||
int msgboxWidth = Math.Max (defaultWidth, Math.Max (title.Length + 8, Math.Max (textWidth + 4, d.GetButtonsWidth ()) + 8)); // textWidth + (left + padding + padding + right)
|
||||
d.Width = msgboxWidth;
|
||||
|
||||
// Setup actions
|
||||
int clicked = -1;
|
||||
for (int n = 0; n < buttonList.Count; n++) {
|
||||
int buttonId = n;
|
||||
buttonList [n].Clicked += () => {
|
||||
clicked = buttonId;
|
||||
Application.RequestStop ();
|
||||
};
|
||||
}
|
||||
|
||||
Application.Run (d);
|
||||
return clicked;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Terminal.Gui;
|
||||
using NStack;
|
||||
using System;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog {
|
||||
[ScenarioMetadata (Name: "Buttons", Description: "Demonstrates all sorts of Buttons")]
|
||||
@@ -19,50 +21,58 @@ namespace UICatalog {
|
||||
|
||||
// This is the default button (IsDefault = true); if user presses ENTER in the TextField
|
||||
// the scenario will quit
|
||||
var defaultButton = new Button ("Quit") {
|
||||
var defaultButton = new Button ("_Quit") {
|
||||
X = Pos.Center (),
|
||||
//TODO: Change to use Pos.AnchorEnd()
|
||||
Y= Pos.Bottom(Win) - 3,
|
||||
Y = Pos.Bottom (Win) - 3,
|
||||
IsDefault = true,
|
||||
Clicked = () => Application.RequestStop (),
|
||||
};
|
||||
Win.Add (defaultButton);
|
||||
|
||||
static void DoMessage (Button button, ustring txt)
|
||||
{
|
||||
button.Clicked = () => {
|
||||
var btnText = button.Text.ToString ();
|
||||
MessageBox.Query (30, 7, "Message", $"Did you click {txt.ToString ()}?", "Yes", "No");
|
||||
};
|
||||
}
|
||||
|
||||
var y = 2;
|
||||
var button = new Button (10, y, "Base Color") {
|
||||
var button = new Button (10, y, "Ba_se Color") {
|
||||
ColorScheme = Colors.Base,
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
};
|
||||
DoMessage (button, button.Text);
|
||||
Win.Add (button);
|
||||
|
||||
y += 2;
|
||||
Win.Add (new Button (10, y, "Error Color") {
|
||||
Win.Add (button = new Button (10, y, "Error Color") {
|
||||
ColorScheme = Colors.Error,
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
});
|
||||
DoMessage (button, button.Text);
|
||||
|
||||
y += 2;
|
||||
Win.Add (new Button (10, y, "Dialog Color") {
|
||||
Win.Add (button = new Button (10, y, "Dialog Color") {
|
||||
ColorScheme = Colors.Dialog,
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
});
|
||||
DoMessage (button, button.Text);
|
||||
|
||||
y += 2;
|
||||
Win.Add (new Button (10, y, "Menu Color") {
|
||||
Win.Add (button = new Button (10, y, "Menu Color") {
|
||||
ColorScheme = Colors.Menu,
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
});
|
||||
DoMessage (button, button.Text);
|
||||
|
||||
y += 2;
|
||||
Win.Add (new Button (10, y, "TopLevel Color") {
|
||||
Win.Add (button = new Button (10, y, "TopLevel Color") {
|
||||
ColorScheme = Colors.TopLevel,
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
});
|
||||
DoMessage (button, button.Text);
|
||||
|
||||
y += 2;
|
||||
Win.Add (new Button (10, y, "A super long button that will probably expose a bug in clipping or wrapping of text. Will it?") {
|
||||
Clicked = () => MessageBox.Query (30, 7, "Message", "Question?", "Yes", "No")
|
||||
Win.Add (button = new Button (10, y, "A super long _Button that will probably expose a bug in clipping or wrapping of text. Will it?") {
|
||||
});
|
||||
DoMessage (button, button.Text);
|
||||
|
||||
y += 2;
|
||||
// Note the 'N' in 'Newline' will be the hotkey
|
||||
@@ -73,13 +83,14 @@ namespace UICatalog {
|
||||
y += 2;
|
||||
// BUGBUG: Buttons don't support specifying hotkeys with _?!?
|
||||
Win.Add (button = new Button ("Te_xt Changer") {
|
||||
X = 10,
|
||||
X = 10,
|
||||
Y = y
|
||||
});
|
||||
button.Clicked = () => button.Text += $"{y++}";
|
||||
|
||||
button.Clicked = () => button.Text += "!";
|
||||
|
||||
Win.Add (new Button ("Lets see if this will move as \"Text Changer\" grows") {
|
||||
X = Pos.Right(button) + 10,
|
||||
X = Pos.Right (button) + 10,
|
||||
Y = y,
|
||||
});
|
||||
|
||||
@@ -99,25 +110,43 @@ namespace UICatalog {
|
||||
|
||||
// Demonstrates how changing the View.Frame property can move Views
|
||||
y += 2;
|
||||
var moveBtn = new Button (10, y, "Move TextField via Frame") {
|
||||
var moveBtn = new Button (10, y, "Move This Button via Frame") {
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
moveBtn.Clicked = () => {
|
||||
edit.Frame = new Rect (edit.Frame.X + 5, edit.Frame.Y, edit.Frame.Width, edit.Frame.Height);
|
||||
moveBtn.Frame = new Rect (moveBtn.Frame.X + 5, moveBtn.Frame.Y, moveBtn.Frame.Width, moveBtn.Frame.Height);
|
||||
};
|
||||
Win.Add (moveBtn);
|
||||
|
||||
// Demonstrates how changing the View.Frame property can NOT resize Views
|
||||
y += 2;
|
||||
var sizeBtn = new Button (10, y, "Grow TextField via Frame") {
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
sizeBtn.Clicked = () => {
|
||||
edit.Frame = new Rect (edit.Frame.X, edit.Frame.Y, edit.Frame.Width + 2, edit.Frame.Height);
|
||||
Win.LayoutSubviews ();
|
||||
};
|
||||
Win.Add (sizeBtn);
|
||||
// Demo changing hotkey
|
||||
ustring MoveHotkey (ustring txt)
|
||||
{
|
||||
// Remove the '_'
|
||||
var i = txt.IndexOf ('_');
|
||||
var start = txt [0, i];
|
||||
txt = start + txt [i + 1, txt.Length];
|
||||
|
||||
// Move over one or go to start
|
||||
i++;
|
||||
if (i >= txt.Length) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
// Slip in the '_'
|
||||
start = txt [0, i];
|
||||
txt = start + ustring.Make ('_') + txt [i, txt.Length];
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
y += 2;
|
||||
var moveHotKeyBtn = new Button (10, y, "Click to Change th_is Button's Hotkey") {
|
||||
ColorScheme = Colors.TopLevel,
|
||||
};
|
||||
moveHotKeyBtn.Clicked = () => {
|
||||
moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
|
||||
};
|
||||
Win.Add (moveHotKeyBtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
171
UICatalog/Scenarios/Dialogs.cs
Normal file
171
UICatalog/Scenarios/Dialogs.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using NStack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace UICatalog {
|
||||
[ScenarioMetadata (Name: "Dialogs", Description: "Demonstrates how to the Dialog class")]
|
||||
[ScenarioCategory ("Controls")]
|
||||
[ScenarioCategory ("Dialogs")]
|
||||
class Dialogs : Scenario {
|
||||
public override void Setup ()
|
||||
{
|
||||
var frame = new FrameView ("Dialog Options") {
|
||||
X = Pos.Center(),
|
||||
Y = 1,
|
||||
Width = Dim.Percent(75),
|
||||
Height = 10
|
||||
};
|
||||
Win.Add (frame);
|
||||
|
||||
var label = new Label ("width:") {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 15,
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var widthEdit = new TextField ("0") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
};
|
||||
frame.Add (widthEdit);
|
||||
|
||||
label = new Label ("height:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width(label),
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var heightEdit = new TextField ("0") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
};
|
||||
frame.Add (heightEdit);
|
||||
|
||||
frame.Add (new Label ("If height & width are both 0,") {
|
||||
X = Pos.Right (widthEdit) + 2,
|
||||
Y = Pos.Top (widthEdit),
|
||||
});
|
||||
frame.Add (new Label ("the Dialog will size to 80% of container.") {
|
||||
X = Pos.Right (heightEdit) + 2,
|
||||
Y = Pos.Top (heightEdit),
|
||||
});
|
||||
|
||||
label = new Label ("Title:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var titleEdit = new TextField ("Title") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = Dim.Fill(),
|
||||
Height = 1
|
||||
};
|
||||
frame.Add (titleEdit);
|
||||
|
||||
label = new Label ("Num Buttons:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (titleEdit),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var numButtonsEdit = new TextField ("3") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
};
|
||||
frame.Add (numButtonsEdit);
|
||||
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit)
|
||||
+ Dim.Height(numButtonsEdit) + 2;
|
||||
|
||||
label = new Label ("Button Pressed:") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 2,
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
Win.Add (label);
|
||||
var buttonPressedLabel = new Label ("") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 4,
|
||||
Width = 25,
|
||||
Height = 1,
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
|
||||
var btnText = new [] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };
|
||||
var showDialogButton = new Button ("Show Dialog") {
|
||||
X = Pos.Center(),
|
||||
Y = Pos.Bottom (frame) + 2 ,
|
||||
IsDefault = true,
|
||||
Clicked = () => {
|
||||
try {
|
||||
int width = int.Parse (widthEdit.Text.ToString ());
|
||||
int height = int.Parse (heightEdit.Text.ToString ());
|
||||
int numButtons = int.Parse (numButtonsEdit.Text.ToString ());
|
||||
|
||||
var buttons = new List<Button> ();
|
||||
var clicked = -1;
|
||||
for (int i = 0; i < numButtons; i++) {
|
||||
var buttonId = i;
|
||||
var button = new Button (btnText [buttonId % 10], is_default: buttonId == 0) {
|
||||
Clicked = () => {
|
||||
clicked = buttonId;
|
||||
Application.RequestStop ();
|
||||
},
|
||||
};
|
||||
buttons.Add(button);
|
||||
}
|
||||
|
||||
// This tests dynamically adding buttons; ensuring the dialog resizes if needed and
|
||||
// the buttons are laid out correctly
|
||||
var dialog = new Dialog (titleEdit.Text, width, height, buttons.ToArray ());
|
||||
var add = new Button ("Add a button") {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Center (),
|
||||
Clicked = () => {
|
||||
var buttonId = buttons.Count;
|
||||
var button = new Button (btnText [buttonId % 10], is_default: buttonId == 0) {
|
||||
Clicked = () => {
|
||||
clicked = buttonId;
|
||||
Application.RequestStop ();
|
||||
},
|
||||
};
|
||||
buttons.Add (button);
|
||||
dialog.AddButton (button);
|
||||
},
|
||||
};
|
||||
dialog.Add (add);
|
||||
|
||||
Application.Run (dialog);
|
||||
buttonPressedLabel.Text = $"{clicked}";
|
||||
|
||||
} catch (FormatException) {
|
||||
buttonPressedLabel.Text = "Invalid Options";
|
||||
}
|
||||
},
|
||||
};
|
||||
Win.Add (showDialogButton);
|
||||
|
||||
Win.Add (buttonPressedLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ namespace UICatalog {
|
||||
private void LoadFile ()
|
||||
{
|
||||
if (!_saved) {
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
if (_fileName != null) {
|
||||
@@ -90,17 +90,17 @@ namespace UICatalog {
|
||||
|
||||
private void Paste ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
private void Cut ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
private void Copy ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
//if (_textView != null && _textView.SelectedLength != 0) {
|
||||
// _textView.Copy ();
|
||||
//}
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace UICatalog {
|
||||
{
|
||||
MemoryStream stream = null;
|
||||
if (!_saved) {
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
if (_fileName != null) {
|
||||
@@ -83,17 +83,17 @@ namespace UICatalog {
|
||||
|
||||
private void Paste ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
private void Cut ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
}
|
||||
|
||||
private void Copy ()
|
||||
{
|
||||
MessageBox.ErrorQuery (0, 10, "Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
|
||||
//if (_textView != null && _textView.SelectedLength != 0) {
|
||||
// _textView.Copy ();
|
||||
//}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using NStack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Terminal.Gui;
|
||||
@@ -18,7 +19,7 @@ namespace UICatalog {
|
||||
};
|
||||
Win.Add (frame);
|
||||
|
||||
var label = new Label ("Width:") {
|
||||
var label = new Label ("width:") {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 15,
|
||||
@@ -26,7 +27,7 @@ namespace UICatalog {
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var widthEdit = new TextField ("50") {
|
||||
var widthEdit = new TextField ("0") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
@@ -34,7 +35,7 @@ namespace UICatalog {
|
||||
};
|
||||
frame.Add (widthEdit);
|
||||
|
||||
label = new Label ("Height:") {
|
||||
label = new Label ("height:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width(label),
|
||||
@@ -42,7 +43,7 @@ namespace UICatalog {
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var heightEdit = new TextField ("6") {
|
||||
var heightEdit = new TextField ("0") {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
@@ -50,6 +51,15 @@ namespace UICatalog {
|
||||
};
|
||||
frame.Add (heightEdit);
|
||||
|
||||
frame.Add (new Label ("If height & width are both 0,") {
|
||||
X = Pos.Right (widthEdit) + 2,
|
||||
Y = Pos.Top (widthEdit),
|
||||
});
|
||||
frame.Add (new Label ("the MessageBox will be sized automatically.") {
|
||||
X = Pos.Right (heightEdit) + 2,
|
||||
Y = Pos.Top (heightEdit),
|
||||
});
|
||||
|
||||
label = new Label ("Title:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
@@ -74,17 +84,19 @@ namespace UICatalog {
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
};
|
||||
frame.Add (label);
|
||||
var messageEdit = new TextField ("Message") {
|
||||
var messageEdit = new TextView () {
|
||||
Text = "Message",
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = Dim.Fill (),
|
||||
Height = 1
|
||||
Height = 5,
|
||||
ColorScheme = Colors.Dialog,
|
||||
};
|
||||
frame.Add (messageEdit);
|
||||
|
||||
label = new Label ("Num Buttons:") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Y = Pos.Bottom (messageEdit),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Right,
|
||||
@@ -130,6 +142,8 @@ namespace UICatalog {
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
|
||||
var btnText = new [] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };
|
||||
|
||||
var showMessageBoxButton = new Button ("Show MessageBox") {
|
||||
X = Pos.Center(),
|
||||
Y = Pos.Bottom (frame) + 2 ,
|
||||
@@ -139,21 +153,23 @@ namespace UICatalog {
|
||||
int width = int.Parse (widthEdit.Text.ToString ());
|
||||
int height = int.Parse (heightEdit.Text.ToString ());
|
||||
int numButtons = int.Parse (numButtonsEdit.Text.ToString ());
|
||||
var btns = new List<string> ();
|
||||
|
||||
var btns = new List<ustring> ();
|
||||
for (int i = 0; i < numButtons; i++) {
|
||||
btns.Add($"Btn {i}");
|
||||
btns.Add(btnText[i % 10]);
|
||||
}
|
||||
if (styleRadioGroup.Selected == 0) {
|
||||
buttonPressedLabel.Text = $"{MessageBox.Query (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), btns.ToArray ())}";
|
||||
} else {
|
||||
buttonPressedLabel.Text = $"{MessageBox.ErrorQuery (width, height, titleEdit.Text.ToString (), messageEdit.Text.ToString (), btns.ToArray ())}";
|
||||
}
|
||||
} catch {
|
||||
} catch (FormatException) {
|
||||
buttonPressedLabel.Text = "Invalid Options";
|
||||
}
|
||||
},
|
||||
};
|
||||
Win.Add (showMessageBoxButton);
|
||||
|
||||
Win.Add (buttonPressedLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,21 +32,20 @@ namespace UICatalog {
|
||||
{
|
||||
static int About ()
|
||||
{
|
||||
//return MessageBox.Query (50, 10, "About UI Catalog", "UI Catalog is a comprehensive sample library for Terminal.Gui", "Ok")
|
||||
return MessageBox.Query ("About UI Catalog", "UI Catalog is a comprehensive sample library for Terminal.Gui", "Ok");
|
||||
|
||||
var about = new Window (new Rect (0, 0, 50, 10), "About UI catalog", 0) {
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Center (),
|
||||
Width = 50,
|
||||
Height = 10,
|
||||
LayoutStyle = LayoutStyle.Computed,
|
||||
ColorScheme = Colors.Error,
|
||||
//var about = new Window (new Rect (0, 0, 50, 10), "About UI catalog", 0) {
|
||||
// X = Pos.Center (),
|
||||
// Y = Pos.Center (),
|
||||
// Width = 50,
|
||||
// Height = 10,
|
||||
// LayoutStyle = LayoutStyle.Computed,
|
||||
// ColorScheme = Colors.Error,
|
||||
|
||||
};
|
||||
//about.Add (new Label ("UI Catalog is a comprehensive sample library for Terminal.Gui"));
|
||||
//};
|
||||
|
||||
Application.Run (about);
|
||||
return 0;
|
||||
//Application.Run (about);
|
||||
//return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -88,7 +87,7 @@ namespace UICatalog {
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
ColorScheme = Colors.Error,
|
||||
Clicked = () => MessageBox.ErrorQuery (30, 10, win.Title.ToString (), "Neat?", "Yes", "No")
|
||||
Clicked = () => MessageBox.ErrorQuery (win.Title.ToString (), "Neat?", "Yes", "No")
|
||||
});
|
||||
var subWin = new Window ("Sub Window") {
|
||||
X = Pos.Percent (0),
|
||||
@@ -128,7 +127,7 @@ namespace UICatalog {
|
||||
X = Pos.Center (),
|
||||
Y = 0,
|
||||
ColorScheme = Colors.Error,
|
||||
//Clicked = () => MessageBox.ErrorQuery (30, 10, frame.Title.ToString (), "Neat?", "Yes", "No")
|
||||
//Clicked = () => MessageBox.ErrorQuery (frame.Title.ToString (), "Neat?", "Yes", "No")
|
||||
});
|
||||
var subWinofFV = new Window ("this is a Sub-Window") {
|
||||
X = Pos.Percent (0),
|
||||
|
||||
@@ -5,7 +5,10 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Terminal.Gui;
|
||||
using Rune = System.Rune;
|
||||
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
@@ -91,11 +94,16 @@ namespace UICatalog {
|
||||
/// </summary>
|
||||
private static void Setup ()
|
||||
{
|
||||
StringBuilder aboutMessage = new StringBuilder ();
|
||||
aboutMessage.AppendLine ("UI Catalog is a comprehensive sample library for Terminal.Gui\n");
|
||||
aboutMessage.AppendLine ($"Version: {typeof(UICatalogApp).Assembly.GetName ().Version}");
|
||||
aboutMessage.Append ($"Using Terminal.Gui Version: {typeof (Terminal.Gui.Application).Assembly.GetName ().Version}\n");
|
||||
|
||||
_menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_File", new MenuItem [] {
|
||||
new MenuItem ("_Quit", "", () => Application.RequestStop() )
|
||||
}),
|
||||
new MenuBarItem ("_About...", "About this app", () => MessageBox.Query (50, 10, "About UI Catalog", "UI Catalog is a comprehensive sample library for Terminal.Gui", "Ok")),
|
||||
new MenuBarItem ("_About...", "About this app", () => MessageBox.Query ("About UI Catalog", aboutMessage.ToString(), "Ok")),
|
||||
});
|
||||
|
||||
_leftPane = new Window ("Categories") {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<StartupObject>UICatalog.UICatalogApp</StartupObject>
|
||||
<AssemblyVersion>1.0.0.1</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user