mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Make it into a library
This commit is contained in:
64
README.md
64
README.md
@@ -4,16 +4,74 @@ This is a simple UI toolkit for .NET.
|
||||
|
||||
It is an updated version of
|
||||
[gui.cs](https://github.com/mono/mono-curses/blob/master/gui.cs) that
|
||||
I wrote for [mono-curses](https://github.com/mono/mono-curses)
|
||||
I wrote for [mono-curses](https://github.com/mono/mono-curses).
|
||||
|
||||
The toolkit contains various controls (labesl, text entry, buttons,
|
||||
radio buttons, checkboxes, dialog boxes, windows, menus) for building
|
||||
text user interfaces, a main loop, is designed to work on Curses and
|
||||
the [Windows
|
||||
Console](https://github.com/migueldeicaza/gui.cs/issues/27), works
|
||||
well on both color and monochrome terminals and has mouse support on
|
||||
terminal emulators that support it.
|
||||
|
||||
# API Documentation
|
||||
|
||||
Go to the [API documentation](https://migueldeicaza.github.io/gui.cs/api/Terminal.html) for details.
|
||||
|
||||
# Sample Usage
|
||||
|
||||
```
|
||||
using Terminal.Gui;
|
||||
|
||||
class Demo {
|
||||
static void Main ()
|
||||
{
|
||||
Application.Init ();
|
||||
var top = Application.Top;
|
||||
|
||||
// Creates the top-level window to show
|
||||
var win = new Window (new Rect (0, 1, top.Frame.Width, top.Frame.Height-1), "MyApp");
|
||||
top.Add (win);
|
||||
|
||||
// Creates a menubar, the item "New" has a help menu.
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_File", new MenuItem [] {
|
||||
new MenuItem ("_New", "Creates new file", NewFile),
|
||||
new MenuItem ("_Close", "", () => Close ()),
|
||||
new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; })
|
||||
}),
|
||||
new MenuBarItem ("_Edit", new MenuItem [] {
|
||||
new MenuItem ("_Copy", "", null),
|
||||
new MenuItem ("C_ut", "", null),
|
||||
new MenuItem ("_Paste", "", null)
|
||||
})
|
||||
});
|
||||
top.Add (menu);
|
||||
|
||||
// Add some controls
|
||||
win.Add (
|
||||
new Label (3, 2, "Login: "),
|
||||
new TextField (14, 2, 40, ""),
|
||||
new Label (3, 4, "Password: "),
|
||||
new TextField (14, 4, 40, "") { Secret = true },
|
||||
new CheckBox (3, 6, "Remember me"),
|
||||
new RadioGroup (3, 8, new [] { "_Personal", "_Company" }),
|
||||
new Button (3, 14, "Ok"),
|
||||
new Button (10, 14, "Cancel"),
|
||||
new Label (3, 18, "Press ESC and 9 to activate the menubar"));
|
||||
|
||||
ShowEntries (win);
|
||||
|
||||
Application.Run ();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This shows a UI like this:
|
||||
|
||||
# Running and Building
|
||||
|
||||
To run this, you will need a peer checkout of mono-ncurses to this
|
||||
directory. I should make a NuGet package at some point.
|
||||
Open the solution and run the sample program.
|
||||
|
||||
# Input Handling
|
||||
|
||||
|
||||
13
Terminal.Gui/MonoCurses/README.md
Normal file
13
Terminal.Gui/MonoCurses/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
This directory contains a copy of the MonoCurses binding from:
|
||||
|
||||
http://github.com/mono/mono-curses
|
||||
|
||||
The source code has been exported in a way that the MonoCurses
|
||||
API is kept private and does not surface to the user, this is
|
||||
done with the command:
|
||||
|
||||
```
|
||||
make publish-to-gui
|
||||
```
|
||||
|
||||
In the MonoCurses package
|
||||
382
Terminal.Gui/MonoCurses/binding.cs
Normal file
382
Terminal.Gui/MonoCurses/binding.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
|
||||
//
|
||||
// binding.cs.in: Core binding for curses.
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza (miguel.de.icaza@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Novell (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Unix.Terminal {
|
||||
|
||||
internal partial class Curses {
|
||||
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct MouseEvent {
|
||||
public short ID;
|
||||
public int X, Y, Z;
|
||||
public Event ButtonState;
|
||||
}
|
||||
|
||||
#region Screen initialization
|
||||
|
||||
[DllImport ("ncurses", EntryPoint="initscr")]
|
||||
extern static internal IntPtr real_initscr ();
|
||||
static int lines, cols;
|
||||
|
||||
static Window main_window;
|
||||
static IntPtr curses_handle, curscr_ptr, lines_ptr, cols_ptr;
|
||||
|
||||
static void FindNCurses ()
|
||||
{
|
||||
if (File.Exists ("/usr/lib/libncurses.dylib"))
|
||||
curses_handle = dlopen ("libncurses.dylib", 0);
|
||||
else
|
||||
curses_handle = dlopen ("libncurses.so", 0);
|
||||
|
||||
if (curses_handle == IntPtr.Zero)
|
||||
throw new Exception ("Could not dlopen ncurses");
|
||||
|
||||
stdscr = read_static_ptr ("stdscr");
|
||||
curscr_ptr = get_ptr ("curscr");
|
||||
lines_ptr = get_ptr ("LINES");
|
||||
cols_ptr = get_ptr ("COLS");
|
||||
}
|
||||
|
||||
static public Window initscr ()
|
||||
{
|
||||
FindNCurses ();
|
||||
|
||||
main_window = new Window (real_initscr ());
|
||||
try {
|
||||
console_sharp_get_dims (out lines, out cols);
|
||||
} catch (DllNotFoundException){
|
||||
endwin ();
|
||||
Console.Error.WriteLine ("Unable to find the @MONO_CURSES@ native library\n" +
|
||||
"this is different than the managed mono-curses.dll\n\n" +
|
||||
"Typically you need to install to a LD_LIBRARY_PATH directory\n" +
|
||||
"or DYLD_LIBRARY_PATH directory or run /sbin/ldconfig");
|
||||
Environment.Exit (1);
|
||||
}
|
||||
return main_window;
|
||||
}
|
||||
|
||||
public static int Lines {
|
||||
get {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Cols {
|
||||
get {
|
||||
return cols;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Returns true if the window changed since the last invocation, as a
|
||||
// side effect, the Lines and Cols properties are updated
|
||||
//
|
||||
public static bool CheckWinChange ()
|
||||
{
|
||||
int l, c;
|
||||
|
||||
console_sharp_get_dims (out l, out c);
|
||||
if (l != lines || c != cols){
|
||||
lines = l;
|
||||
cols = c;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int endwin ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public bool isendwin ();
|
||||
|
||||
//
|
||||
// Screen operations are flagged as internal, as we need to
|
||||
// catch all changes so we can update newscr, curscr, stdscr
|
||||
//
|
||||
[DllImport ("ncurses")]
|
||||
extern static public IntPtr internal_newterm (string type, IntPtr file_outfd, IntPtr file_infd);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public IntPtr internal_set_term (IntPtr newscreen);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal void internal_delscreen (IntPtr sp);
|
||||
#endregion
|
||||
|
||||
#region Input Options
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int cbreak ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int nocbreak ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int echo ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int noecho ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int halfdelay (int t);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int raw ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int noraw ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public void noqiflush ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public void qiflush ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int typeahead (IntPtr fd);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static public int timeout (int delay);
|
||||
|
||||
//
|
||||
// Internal, as they are exposed in Window
|
||||
//
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal int wtimeout (IntPtr win, int delay);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal int notimeout (IntPtr win, bool bf);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal int keypad (IntPtr win, bool bf);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal int meta (IntPtr win, bool bf);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern static internal int intrflush (IntPtr win, bool bf);
|
||||
#endregion
|
||||
|
||||
#region Output Options
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int clearok (IntPtr win, bool bf);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int idlok (IntPtr win, bool bf);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static void idcok (IntPtr win, bool bf);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static void immedok (IntPtr win, bool bf);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int leaveok (IntPtr win, bool bf);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int wsetscrreg (IntPtr win, int top, int bot);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int scrollok (IntPtr win, bool bf);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int nl();
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int nonl();
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int setscrreg (int top, int bot);
|
||||
|
||||
#endregion
|
||||
|
||||
#region refresh functions
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int refresh ();
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int doupdate();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int wrefresh (IntPtr win);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int redrawwin (IntPtr win);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int wredrawwin (IntPtr win, int beg_line, int num_lines);
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int wnoutrefresh (IntPtr win);
|
||||
#endregion
|
||||
|
||||
#region Output
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int move (int line, int col);
|
||||
|
||||
[DllImport ("ncurses", EntryPoint="addch")]
|
||||
extern internal static int _addch (int ch);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int addstr (string s);
|
||||
|
||||
public static int addstr (string format, params object [] args)
|
||||
{
|
||||
var s = string.Format (format, args);
|
||||
return addstr (s);
|
||||
}
|
||||
|
||||
static char [] r = new char [1];
|
||||
|
||||
//
|
||||
// Have to wrap the native addch, as it can not
|
||||
// display unicode characters, we have to use addstr
|
||||
// for that. but we need addch to render special ACS
|
||||
// characters
|
||||
//
|
||||
public static int addch (int ch)
|
||||
{
|
||||
if (ch < 127 || ch > 0xffff )
|
||||
return _addch (ch);
|
||||
char c = (char) ch;
|
||||
return addstr (new String (c, 1));
|
||||
}
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int wmove (IntPtr win, int line, int col);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int waddch (IntPtr win, int ch);
|
||||
#endregion
|
||||
|
||||
#region Attributes
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int attron (int attrs);
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int attroff (int attrs);
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int attrset (int attrs);
|
||||
#endregion
|
||||
|
||||
#region Input
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int getch ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int get_wch (out int sequence);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int ungetch (int ch);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern public static int mvgetch (int y, int x);
|
||||
#endregion
|
||||
|
||||
#region Colors
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static bool has_colors ();
|
||||
public static bool HasColors => has_colors ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int start_color ();
|
||||
public static int StartColor () => start_color ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int init_pair (short pair, short f, short b);
|
||||
public static int InitColorPair (short pair, short foreground, short background) => init_pair (pair, foreground, background);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int use_default_colors ();
|
||||
public static int UseDefaultColors () => use_default_colors ();
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
extern internal static int COLOR_PAIRS();
|
||||
public static int ColorPairs => COLOR_PAIRS();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
[DllImport ("libc")]
|
||||
extern static IntPtr dlopen (string file, int mode);
|
||||
|
||||
[DllImport ("libc")]
|
||||
extern static IntPtr dlsym (IntPtr handle, string symbol);
|
||||
|
||||
static IntPtr stdscr;
|
||||
|
||||
static IntPtr get_ptr (string key)
|
||||
{
|
||||
var ptr = dlsym (curses_handle, key);
|
||||
if (ptr == IntPtr.Zero)
|
||||
throw new Exception ("Could not load the key " + key);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
internal static IntPtr read_static_ptr (string key)
|
||||
{
|
||||
var ptr = get_ptr (key);
|
||||
return Marshal.ReadIntPtr (ptr);
|
||||
}
|
||||
|
||||
internal static IntPtr console_sharp_get_stdscr () => stdscr;
|
||||
|
||||
|
||||
#region Helpers
|
||||
internal static IntPtr console_sharp_get_curscr ()
|
||||
{
|
||||
return Marshal.ReadIntPtr (curscr_ptr);
|
||||
}
|
||||
|
||||
internal static void console_sharp_get_dims (out int lines, out int cols)
|
||||
{
|
||||
lines = Marshal.ReadInt32 (lines_ptr);
|
||||
cols = Marshal.ReadInt32 (cols_ptr);
|
||||
}
|
||||
|
||||
[DllImport ("ncurses", EntryPoint="mousemask")]
|
||||
extern static IntPtr call_mousemask (IntPtr newmask, out IntPtr oldmask);
|
||||
|
||||
public static Event mousemask (Event newmask, out Event oldmask)
|
||||
{
|
||||
IntPtr e;
|
||||
var ret = (Event) call_mousemask ((IntPtr) newmask, out e);
|
||||
oldmask = (Event) e;
|
||||
return ret;
|
||||
}
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
public extern static uint getmouse (out MouseEvent ev);
|
||||
|
||||
[DllImport ("ncurses")]
|
||||
public extern static uint ungetmouse (ref MouseEvent ev);
|
||||
#endregion
|
||||
|
||||
// We encode ESC + char (what Alt-char generates) as 0x2000 + char
|
||||
public const int KeyAlt = 0x2000;
|
||||
|
||||
static public int IsAlt (int key)
|
||||
{
|
||||
if ((key & KeyAlt) != 0)
|
||||
return key & ~KeyAlt;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Terminal.Gui/MonoCurses/constants.cs
Normal file
92
Terminal.Gui/MonoCurses/constants.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is autogenerated by the attrib.c program, do not edit
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Unix.Terminal {
|
||||
internal partial class Curses {
|
||||
public const int A_NORMAL = unchecked((int)0x0);
|
||||
public const int A_STANDOUT = unchecked((int)0x10000);
|
||||
public const int A_UNDERLINE = unchecked((int)0x20000);
|
||||
public const int A_REVERSE = unchecked((int)0x40000);
|
||||
public const int A_BLINK = unchecked((int)0x80000);
|
||||
public const int A_DIM = unchecked((int)0x100000);
|
||||
public const int A_BOLD = unchecked((int)0x200000);
|
||||
public const int A_PROTECT = unchecked((int)0x1000000);
|
||||
public const int A_INVIS = unchecked((int)0x800000);
|
||||
public const int ACS_LLCORNER = unchecked((int)0x40006d);
|
||||
public const int ACS_LRCORNER = unchecked((int)0x40006a);
|
||||
public const int ACS_HLINE = unchecked((int)0x400071);
|
||||
public const int ACS_ULCORNER = unchecked((int)0x40006c);
|
||||
public const int ACS_URCORNER = unchecked((int)0x40006b);
|
||||
public const int ACS_VLINE = unchecked((int)0x400078);
|
||||
public const int COLOR_BLACK = unchecked((int)0x0);
|
||||
public const int COLOR_RED = unchecked((int)0x1);
|
||||
public const int COLOR_GREEN = unchecked((int)0x2);
|
||||
public const int COLOR_YELLOW = unchecked((int)0x3);
|
||||
public const int COLOR_BLUE = unchecked((int)0x4);
|
||||
public const int COLOR_MAGENTA = unchecked((int)0x5);
|
||||
public const int COLOR_CYAN = unchecked((int)0x6);
|
||||
public const int COLOR_WHITE = unchecked((int)0x7);
|
||||
public const int KEY_CODE_YES = unchecked((int)0x100);
|
||||
internal enum Event : long {
|
||||
Button1Pressed = unchecked((int)0x2),
|
||||
Button1Released = unchecked((int)0x1),
|
||||
Button1Clicked = unchecked((int)0x4),
|
||||
Button1DoubleClicked = unchecked((int)0x8),
|
||||
Button1TripleClicked = unchecked((int)0x10),
|
||||
Button2Pressed = unchecked((int)0x80),
|
||||
Button2Released = unchecked((int)0x40),
|
||||
Button2Clicked = unchecked((int)0x100),
|
||||
Button2DoubleClicked = unchecked((int)0x200),
|
||||
Button2TrippleClicked = unchecked((int)0x400),
|
||||
Button3Pressed = unchecked((int)0x2000),
|
||||
Button3Released = unchecked((int)0x1000),
|
||||
Button3Clicked = unchecked((int)0x4000),
|
||||
Button3DoubleClicked = unchecked((int)0x8000),
|
||||
Button3TripleClicked = unchecked((int)0x10000),
|
||||
Button4Pressed = unchecked((int)0x80000),
|
||||
Button4Released = unchecked((int)0x40000),
|
||||
Button4Clicked = unchecked((int)0x100000),
|
||||
Button4DoubleClicked = unchecked((int)0x200000),
|
||||
Button4TripleClicked = unchecked((int)0x400000),
|
||||
ButtonShift = unchecked((int)0x2000000),
|
||||
ButtonCtrl = unchecked((int)0x1000000),
|
||||
ButtonAlt = unchecked((int)0x4000000),
|
||||
ReportMousePosition = unchecked((int)0x8000000),
|
||||
AllEvents = unchecked((int)0x7ffffff),
|
||||
}
|
||||
public const int ERR = unchecked((int)0xffffffff);
|
||||
public const int KeyBackspace = unchecked((int)0x107);
|
||||
public const int KeyUp = unchecked((int)0x103);
|
||||
public const int KeyDown = unchecked((int)0x102);
|
||||
public const int KeyLeft = unchecked((int)0x104);
|
||||
public const int KeyRight = unchecked((int)0x105);
|
||||
public const int KeyNPage = unchecked((int)0x152);
|
||||
public const int KeyPPage = unchecked((int)0x153);
|
||||
public const int KeyHome = unchecked((int)0x106);
|
||||
public const int KeyMouse = unchecked((int)0x199);
|
||||
public const int KeyEnd = unchecked((int)0x168);
|
||||
public const int KeyDeleteChar = unchecked((int)0x14a);
|
||||
public const int KeyInsertChar = unchecked((int)0x14b);
|
||||
public const int KeyBackTab = unchecked((int)0x161);
|
||||
public const int KeyF1 = unchecked((int)0x109);
|
||||
public const int KeyF2 = unchecked((int)0x10a);
|
||||
public const int KeyF3 = unchecked((int)0x10b);
|
||||
public const int KeyF4 = unchecked((int)0x10c);
|
||||
public const int KeyF5 = unchecked((int)0x10d);
|
||||
public const int KeyF6 = unchecked((int)0x10e);
|
||||
public const int KeyF7 = unchecked((int)0x10f);
|
||||
public const int KeyF8 = unchecked((int)0x110);
|
||||
public const int KeyF9 = unchecked((int)0x111);
|
||||
public const int KeyF10 = unchecked((int)0x112);
|
||||
public const int KeyResize = unchecked((int)0x19a);
|
||||
|
||||
|
||||
static public int ColorPair(int n){
|
||||
return 0 + n * 256;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
172
Terminal.Gui/MonoCurses/handles.cs
Normal file
172
Terminal.Gui/MonoCurses/handles.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// handles.cs: OO wrappers for some curses objects
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza (miguel.de.icaza@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2007 Novell (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Unix.Terminal {
|
||||
|
||||
internal partial class Curses {
|
||||
internal class Window {
|
||||
public readonly IntPtr Handle;
|
||||
static Window curscr;
|
||||
static Window stdscr;
|
||||
|
||||
static Window ()
|
||||
{
|
||||
Curses.initscr ();
|
||||
stdscr = new Window (Curses.console_sharp_get_stdscr ());
|
||||
curscr = new Window (Curses.console_sharp_get_curscr ());
|
||||
}
|
||||
|
||||
internal Window (IntPtr handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
static public Window Standard {
|
||||
get {
|
||||
return stdscr;
|
||||
}
|
||||
}
|
||||
|
||||
static public Window Current {
|
||||
get {
|
||||
return curscr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int wtimeout (int delay)
|
||||
{
|
||||
return Curses.wtimeout (Handle, delay);
|
||||
}
|
||||
|
||||
public int notimeout (bool bf)
|
||||
{
|
||||
return Curses.notimeout (Handle, bf);
|
||||
}
|
||||
|
||||
public int keypad (bool bf)
|
||||
{
|
||||
return Curses.keypad (Handle, bf);
|
||||
}
|
||||
|
||||
public int meta (bool bf)
|
||||
{
|
||||
return Curses.meta (Handle, bf);
|
||||
}
|
||||
|
||||
public int intrflush (bool bf)
|
||||
{
|
||||
return Curses.intrflush (Handle, bf);
|
||||
}
|
||||
|
||||
public int clearok (bool bf)
|
||||
{
|
||||
return Curses.clearok (Handle, bf);
|
||||
}
|
||||
|
||||
public int idlok (bool bf)
|
||||
{
|
||||
return Curses.idlok (Handle, bf);
|
||||
}
|
||||
|
||||
public void idcok (bool bf)
|
||||
{
|
||||
Curses.idcok (Handle, bf);
|
||||
}
|
||||
|
||||
public void immedok (bool bf)
|
||||
{
|
||||
Curses.immedok (Handle, bf);
|
||||
}
|
||||
|
||||
public int leaveok (bool bf)
|
||||
{
|
||||
return Curses.leaveok (Handle, bf);
|
||||
}
|
||||
|
||||
public int setscrreg (int top, int bot)
|
||||
{
|
||||
return Curses.wsetscrreg (Handle, top, bot);
|
||||
}
|
||||
|
||||
public int scrollok (bool bf)
|
||||
{
|
||||
return Curses.scrollok (Handle, bf);
|
||||
}
|
||||
|
||||
public int wrefresh ()
|
||||
{
|
||||
return Curses.wrefresh (Handle);
|
||||
}
|
||||
|
||||
public int redrawwin ()
|
||||
{
|
||||
return Curses.redrawwin (Handle);
|
||||
}
|
||||
|
||||
public int wredrawwin (int beg_line, int num_lines)
|
||||
{
|
||||
return Curses.wredrawwin (Handle, beg_line, num_lines);
|
||||
}
|
||||
|
||||
public int wnoutrefresh ()
|
||||
{
|
||||
return Curses.wnoutrefresh (Handle);
|
||||
}
|
||||
|
||||
public int move (int line, int col)
|
||||
{
|
||||
return Curses.wmove (Handle, line, col);
|
||||
}
|
||||
|
||||
public int addch (char ch)
|
||||
{
|
||||
return Curses.waddch (Handle, ch);
|
||||
}
|
||||
|
||||
public int refresh ()
|
||||
{
|
||||
return Curses.wrefresh (Handle);
|
||||
}
|
||||
}
|
||||
|
||||
// Currently unused, to do later
|
||||
internal class Screen {
|
||||
public readonly IntPtr Handle;
|
||||
|
||||
internal Screen (IntPtr handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
362
Terminal.Gui/MonoCurses/mainloop.cs
Normal file
362
Terminal.Gui/MonoCurses/mainloop.cs
Normal file
@@ -0,0 +1,362 @@
|
||||
//
|
||||
// mainloop.cs: Simple managed mainloop implementation.
|
||||
//
|
||||
// Authors:
|
||||
// Miguel de Icaza (miguel.de.icaza@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2011 Novell (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
using Mono.Unix.Native;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mono.Terminal {
|
||||
|
||||
/// <summary>
|
||||
/// Simple main loop implementation that can be used to monitor
|
||||
/// file descriptor, run timers and idle handlers.
|
||||
/// </summary>
|
||||
public class MainLoop {
|
||||
/// <summary>
|
||||
/// Condition on which to wake up from file descriptor activity
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum Condition {
|
||||
/// <summary>
|
||||
/// There is data to read
|
||||
/// </summary>
|
||||
PollIn = 1,
|
||||
/// <summary>
|
||||
/// Writing to the specified descriptor will not block
|
||||
/// </summary>
|
||||
PollOut = 2,
|
||||
/// <summary>
|
||||
/// There is urgent data to read
|
||||
/// </summary>
|
||||
PollPri = 4,
|
||||
/// <summary>
|
||||
/// Error condition on output
|
||||
/// </summary>
|
||||
PollErr = 8,
|
||||
/// <summary>
|
||||
/// Hang-up on output
|
||||
/// </summary>
|
||||
PollHup = 16,
|
||||
/// <summary>
|
||||
/// File descriptor is not open.
|
||||
/// </summary>
|
||||
PollNval = 32
|
||||
}
|
||||
|
||||
class Watch {
|
||||
public int File;
|
||||
public Condition Condition;
|
||||
public Func<MainLoop,bool> Callback;
|
||||
}
|
||||
|
||||
class Timeout {
|
||||
public TimeSpan Span;
|
||||
public Func<MainLoop,bool> Callback;
|
||||
}
|
||||
|
||||
Dictionary <int, Watch> descriptorWatchers = new Dictionary<int,Watch>();
|
||||
SortedList <double, Timeout> timeouts = new SortedList<double,Timeout> ();
|
||||
List<Func<bool>> idleHandlers = new List<Func<bool>> ();
|
||||
|
||||
Pollfd [] pollmap;
|
||||
bool poll_dirty = true;
|
||||
int [] wakeupPipes = new int [2];
|
||||
static IntPtr ignore = Marshal.AllocHGlobal (1);
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public MainLoop ()
|
||||
{
|
||||
Syscall.pipe (wakeupPipes);
|
||||
AddWatch (wakeupPipes [0], Condition.PollIn, ml => {
|
||||
Syscall.read (wakeupPipes [0], ignore, 1);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void Wakeup ()
|
||||
{
|
||||
Syscall.write (wakeupPipes [1], ignore, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs @action on the thread that is processing events
|
||||
/// </summary>
|
||||
public void Invoke (Action action)
|
||||
{
|
||||
AddIdle (()=> {
|
||||
action ();
|
||||
return false;
|
||||
});
|
||||
Wakeup ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the specified @idleHandler on the idle loop. The return value is a token to remove it.
|
||||
/// </summary>
|
||||
public Func<bool> AddIdle (Func<bool> idleHandler)
|
||||
{
|
||||
lock (idleHandlers)
|
||||
idleHandlers.Add (idleHandler);
|
||||
return idleHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified idleHandler from processing.
|
||||
/// </summary>
|
||||
public void RemoveIdle (Func<bool> idleHandler)
|
||||
{
|
||||
lock (idleHandler)
|
||||
idleHandlers.Remove (idleHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Watches a file descriptor for activity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When the condition is met, the provided callback
|
||||
/// is invoked. If the callback returns false, the
|
||||
/// watch is automatically removed.
|
||||
///
|
||||
/// The return value is a token that represents this watch, you can
|
||||
/// use this token to remove the watch by calling RemoveWatch.
|
||||
/// </remarks>
|
||||
public object AddWatch (int fileDescriptor, Condition condition, Func<MainLoop,bool> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException ("callback");
|
||||
|
||||
var watch = new Watch () { Condition = condition, Callback = callback, File = fileDescriptor };
|
||||
descriptorWatchers [fileDescriptor] = watch;
|
||||
poll_dirty = true;
|
||||
return watch;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an active watch from the mainloop.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The token parameter is the value returned from AddWatch
|
||||
/// </remarks>
|
||||
public void RemoveWatch (object token)
|
||||
{
|
||||
var watch = token as Watch;
|
||||
if (watch == null)
|
||||
return;
|
||||
descriptorWatchers.Remove (watch.File);
|
||||
}
|
||||
|
||||
void AddTimeout (TimeSpan time, Timeout timeout)
|
||||
{
|
||||
timeouts.Add ((DateTime.UtcNow + time).Ticks, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a timeout to the mainloop.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When time time specified passes, the callback will be invoked.
|
||||
/// If the callback returns true, the timeout will be reset, repeating
|
||||
/// the invocation. If it returns false, the timeout will stop.
|
||||
///
|
||||
/// The returned value is a token that can be used to stop the timeout
|
||||
/// by calling RemoveTimeout.
|
||||
/// </remarks>
|
||||
public object AddTimeout (TimeSpan time, Func<MainLoop,bool> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException ("callback");
|
||||
var timeout = new Timeout () {
|
||||
Span = time,
|
||||
Callback = callback
|
||||
};
|
||||
AddTimeout (time, timeout);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a previously scheduled timeout
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The token parameter is the value returned by AddTimeout.
|
||||
/// </remarks>
|
||||
public void RemoveTimeout (object token)
|
||||
{
|
||||
var idx = timeouts.IndexOfValue (token as Timeout);
|
||||
if (idx == -1)
|
||||
return;
|
||||
timeouts.RemoveAt (idx);
|
||||
}
|
||||
|
||||
static PollEvents MapCondition (Condition condition)
|
||||
{
|
||||
PollEvents ret = 0;
|
||||
if ((condition & Condition.PollIn) != 0)
|
||||
ret |= PollEvents.POLLIN;
|
||||
if ((condition & Condition.PollOut) != 0)
|
||||
ret |= PollEvents.POLLOUT;
|
||||
if ((condition & Condition.PollPri) != 0)
|
||||
ret |= PollEvents.POLLPRI;
|
||||
if ((condition & Condition.PollErr) != 0)
|
||||
ret |= PollEvents.POLLERR;
|
||||
if ((condition & Condition.PollHup) != 0)
|
||||
ret |= PollEvents.POLLHUP;
|
||||
if ((condition & Condition.PollNval) != 0)
|
||||
ret |= PollEvents.POLLNVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UpdatePollMap ()
|
||||
{
|
||||
if (!poll_dirty)
|
||||
return;
|
||||
poll_dirty = false;
|
||||
|
||||
pollmap = new Pollfd [descriptorWatchers.Count];
|
||||
int i = 0;
|
||||
foreach (var fd in descriptorWatchers.Keys){
|
||||
pollmap [i].fd = fd;
|
||||
pollmap [i].events = MapCondition (descriptorWatchers [fd].Condition);
|
||||
}
|
||||
}
|
||||
|
||||
void RunTimers ()
|
||||
{
|
||||
long now = DateTime.UtcNow.Ticks;
|
||||
var copy = timeouts;
|
||||
timeouts = new SortedList<double,Timeout> ();
|
||||
foreach (var k in copy.Keys){
|
||||
if (k >= now)
|
||||
break;
|
||||
|
||||
var timeout = copy [k];
|
||||
if (timeout.Callback (this))
|
||||
AddTimeout (timeout.Span, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void RunIdle ()
|
||||
{
|
||||
List<Func<bool>> iterate;
|
||||
lock (idleHandlers){
|
||||
iterate = idleHandlers;
|
||||
idleHandlers = new List<Func<bool>> ();
|
||||
}
|
||||
|
||||
foreach (var idle in iterate){
|
||||
if (idle ())
|
||||
lock (idleHandlers)
|
||||
idleHandlers.Add (idle);
|
||||
}
|
||||
}
|
||||
|
||||
bool running;
|
||||
|
||||
/// <summary>
|
||||
/// Stops the mainloop.
|
||||
/// </summary>
|
||||
public void Stop ()
|
||||
{
|
||||
running = false;
|
||||
Wakeup ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether there are pending events to be processed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can use this method if you want to probe if events are pending.
|
||||
/// Typically used if you need to flush the input queue while still
|
||||
/// running some of your own code in your main thread.
|
||||
/// </remarks>
|
||||
public bool EventsPending (bool wait = false)
|
||||
{
|
||||
long now = DateTime.UtcNow.Ticks;
|
||||
int pollTimeout, n;
|
||||
if (timeouts.Count > 0)
|
||||
pollTimeout = (int) ((timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
|
||||
else
|
||||
pollTimeout = -1;
|
||||
|
||||
if (!wait)
|
||||
pollTimeout = 0;
|
||||
|
||||
UpdatePollMap ();
|
||||
|
||||
n = Syscall.poll (pollmap, (uint) pollmap.Length, pollTimeout);
|
||||
int ic;
|
||||
lock (idleHandlers)
|
||||
ic = idleHandlers.Count;
|
||||
return n > 0 || timeouts.Count > 0 && ((timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs one iteration of timers and file watches
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You use this to process all pending events (timers, idle handlers and file watches).
|
||||
///
|
||||
/// You can use it like this:
|
||||
/// while (main.EvensPending ()) MainIteration ();
|
||||
/// </remarks>
|
||||
public void MainIteration ()
|
||||
{
|
||||
if (timeouts.Count > 0)
|
||||
RunTimers ();
|
||||
|
||||
foreach (var p in pollmap){
|
||||
Watch watch;
|
||||
|
||||
if (p.revents == 0)
|
||||
continue;
|
||||
|
||||
if (!descriptorWatchers.TryGetValue (p.fd, out watch))
|
||||
continue;
|
||||
if (!watch.Callback (this))
|
||||
descriptorWatchers.Remove (p.fd);
|
||||
}
|
||||
if (idleHandlers.Count > 0)
|
||||
RunIdle ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the mainloop.
|
||||
/// </summary>
|
||||
public void Run ()
|
||||
{
|
||||
bool prev = running;
|
||||
running = true;
|
||||
while (running){
|
||||
EventsPending (true);
|
||||
MainIteration ();
|
||||
}
|
||||
running = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Terminal.Gui/Terminal.Gui.csproj
Normal file
61
Terminal.Gui/Terminal.Gui.csproj
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Terminal.Gui</RootNamespace>
|
||||
<AssemblyName>Terminal.Gui</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Mono.Posix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
<Folder Include="Types\" />
|
||||
<Folder Include="Views\" />
|
||||
<Folder Include="MonoCurses\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Types\Point.cs" />
|
||||
<Compile Include="Types\Rect.cs" />
|
||||
<Compile Include="Types\Size.cs" />
|
||||
<Compile Include="Views\Button.cs" />
|
||||
<Compile Include="Views\Checkbox.cs" />
|
||||
<Compile Include="Views\Dialog.cs" />
|
||||
<Compile Include="Views\Label.cs" />
|
||||
<Compile Include="Views\Menu.cs" />
|
||||
<Compile Include="Views\MessageBox.cs" />
|
||||
<Compile Include="Views\RadioGroup.cs" />
|
||||
<Compile Include="Views\ScrollView.cs" />
|
||||
<Compile Include="Views\TextField.cs" />
|
||||
<Compile Include="Core.cs" />
|
||||
<Compile Include="Driver.cs" />
|
||||
<Compile Include="Event.cs" />
|
||||
<Compile Include="MonoCurses\binding.cs" />
|
||||
<Compile Include="MonoCurses\constants.cs" />
|
||||
<Compile Include="MonoCurses\handles.cs" />
|
||||
<Compile Include="MonoCurses\mainloop.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -33,30 +33,13 @@
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Core.cs" />
|
||||
<Compile Include="Driver.cs" />
|
||||
<Compile Include="Event.cs" />
|
||||
<Compile Include="Types\Point.cs" />
|
||||
<Compile Include="Types\Rect.cs" />
|
||||
<Compile Include="Types\Size.cs" />
|
||||
<Compile Include="demo.cs" />
|
||||
<Compile Include="Views\Label.cs" />
|
||||
<Compile Include="Views\TextField.cs" />
|
||||
<Compile Include="Views\Button.cs" />
|
||||
<Compile Include="Views\Checkbox.cs" />
|
||||
<Compile Include="Views\Menu.cs" />
|
||||
<Compile Include="Views\ScrollView.cs" />
|
||||
<Compile Include="Views\Dialog.cs" />
|
||||
<Compile Include="Views\RadioGroup.cs" />
|
||||
<Compile Include="Views\MessageBox.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mono-curses.dll">
|
||||
<HintPath>$(MSBuildProjectDirectory)/../mono-curses/mono-curses.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\" />
|
||||
<ProjectReference Include="Terminal.Gui\Terminal.Gui.csproj">
|
||||
<Project>{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}</Project>
|
||||
<Name>Terminal.Gui</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Terminal", "Terminal.csproj", "{B0A602CD-E176-449D-8663-64238D54F857}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Terminal.Gui", "Terminal.Gui\Terminal.Gui.csproj", "{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
@@ -13,6 +15,10 @@ Global
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|x86.Build.0 = Debug|x86
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Release|x86.ActiveCfg = Release|x86
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Release|x86.Build.0 = Release|x86
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
|
||||
18
demo.cs
18
demo.cs
@@ -13,15 +13,15 @@ class Demo {
|
||||
static void ShowEntries (View container)
|
||||
{
|
||||
container.Add (
|
||||
new Label (3, 2, "Login: "),
|
||||
new TextField (14, 2, 40, ""),
|
||||
new Label (3, 4, "Password: "),
|
||||
new TextField (14, 4, 40, "") { Secret = true },
|
||||
new CheckBox (3, 6, "Remember me"),
|
||||
new RadioGroup (3, 8, new [] { "_Personal", "_Company" }),
|
||||
new Button (3, 14, "Ok"),
|
||||
new Button (10, 14, "Cancel"),
|
||||
new Label (3, 18, "Press ESC and 9 to activate the menubar")
|
||||
new Label (3, 6, "Login: "),
|
||||
new TextField (14, 6, 40, ""),
|
||||
new Label (3, 8, "Password: "),
|
||||
new TextField (14, 8, 40, "") { Secret = true },
|
||||
new CheckBox (3, 10, "Remember me"),
|
||||
new RadioGroup (3, 12, new [] { "_Personal", "_Company" }),
|
||||
new Button (3, 18, "Ok"),
|
||||
new Button (10, 18, "Cancel"),
|
||||
new Label (3, 22, "Press ESC and 9 to activate the menubar")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user