123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- using System;
- namespace Terminal {
- /// <summary>
- /// A menu item has a title, an associated help text, and an action to execute on activation.
- /// </summary>
- public class MenuItem {
- public MenuItem (string title, string help, Action action)
- {
- Title = title ?? "";
- Help = help ?? "";
- Action = action;
- Width = Title.Length + Help.Length + 1;
- }
- public string Title { get; set; }
- public string Help { get; set; }
- public Action Action { get; set; }
- public int Width { get; set; }
- }
- /// <summary>
- /// A menu bar item contains other menu items.
- /// </summary>
- public class MenuBarItem {
- public MenuBarItem (string title, MenuItem [] children)
- {
- Title = title ?? "";
- Children = children;
- }
- public string Title { get; set; }
- public MenuItem [] Children { get; set; }
- public int Current { get; set; }
- }
- /// <summary>
- /// A menu bar for your application.
- /// </summary>
- public class MenuBar : View {
- public MenuBarItem [] Menus { get; set; }
- int selected;
- Action action;
- public MenuBar (MenuBarItem [] menus) : base (new Rect (0, 0, Application.Driver.Cols, 1))
- {
- Menus = menus;
- CanFocus = false;
- selected = -1;
- }
- /// <summary>
- /// Activates the menubar
- /// </summary>
- public void Activate (int idx)
- {
- if (idx < 0 || idx > Menus.Length)
- throw new ArgumentException ("idx");
- action = null;
- selected = idx;
- foreach (var m in Menus)
- m.Current = 0;
- // TODO: Application.Run (this);
- selected = -1;
- SuperView.SetNeedsDisplay ();
- if (action != null)
- action ();
- }
- void DrawMenu (int idx, int col, int line)
- {
- int max = 0;
- var menu = Menus [idx];
- if (menu.Children == null)
- return;
- foreach (var m in menu.Children) {
- if (m == null)
- continue;
- if (m.Width > max)
- max = m.Width;
- }
- max += 4;
- DrawFrame (new Rect (col, line, max, menu.Children.Length + 2), true);
- for (int i = 0; i < menu.Children.Length; i++) {
- var item = menu.Children [i];
- Move (line + 1 + i, col + 1);
- Driver.SetAttribute (item == null ? Colors.Base.Focus : i == menu.Current ? Colors.Menu.MarkedSelected : Colors.Menu.Marked);
- for (int p = 0; p < max - 2; p++)
- if (item == null)
- Driver.AddSpecial (SpecialChar.HLine);
- else
- Driver.AddCh (' ');
- if (item == null)
- continue;
- Move (line + 1 + i, col + 2);
- DrawHotString (item.Title,
- i == menu.Current ? Colors.Menu.HotFocus: Colors.Menu.HotNormal,
- i == menu.Current ? Colors.Menu.MarkedSelected : Colors.Menu.Marked);
- // The help string
- var l = item.Help.Length;
- Move (col + max - l - 2, line + 1 + i);
- Driver.AddStr (item.Help);
- }
- }
- public override void Redraw (Rect region)
- {
- Move (0, 0);
- Driver.SetAttribute (Colors.Base.Focus);
- for (int i = 0; i < Frame.Width; i++)
- Driver.AddCh (' ');
- Move (1, 0);
- int pos = 0;
- for (int i = 0; i < Menus.Length; i++) {
- var menu = Menus [i];
- if (i == selected) {
- DrawMenu (i, pos, 1);
- Driver.SetAttribute (Colors.Menu.MarkedSelected);
- } else
- Driver.SetAttribute (Colors.Menu.Focus);
- Move (pos, 0);
- Driver.AddCh (' ');
- Driver.AddStr(menu.Title);
- Driver.AddCh (' ');
- if (HasFocus && i == selected)
- Driver.SetAttribute (Colors.Menu.MarkedSelected);
- else
- Driver.SetAttribute (Colors.Menu.Marked);
- Driver.AddStr (" ");
- pos += menu.Title.Length + 4;
- }
- PositionCursor ();
- }
- public override void PositionCursor ()
- {
- int pos = 0;
- for (int i = 0; i < Menus.Length; i++) {
- if (i == selected) {
- pos++;
- Move (pos, 0);
- return;
- } else {
- pos += Menus [i].Title.Length + 4;
- }
- }
- Move (0, 0);
- }
- void Selected (MenuItem item)
- {
- // TODO: Running = false;
- action = item.Action;
- }
- public override bool ProcessKey (KeyEvent kb)
- {
- switch (kb.Key) {
- case Key.CursorUp:
- if (Menus [selected].Children == null)
- return false;
- int current = Menus [selected].Current;
- do {
- current--;
- if (current < 0)
- current = Menus [selected].Children.Length - 1;
- } while (Menus [selected].Children [current] == null);
- Menus [selected].Current = current;
- SetNeedsDisplay ();
- return true;
- case Key.CursorDown:
- if (Menus [selected].Children == null)
- return false;
- do {
- Menus [selected].Current = (Menus [selected].Current + 1) % Menus [selected].Children.Length;
- } while (Menus [selected].Children [Menus [selected].Current] == null);
- SetNeedsDisplay ();
- break;
- case Key.CursorLeft:
- selected--;
- if (selected < 0)
- selected = Menus.Length - 1;
- break;
- case Key.CursorRight:
- selected = (selected + 1) % Menus.Length;
- break;
- case Key.Enter:
- if (Menus [selected].Children == null)
- return false;
- Selected (Menus [selected].Children [Menus [selected].Current]);
- break;
- case Key.Esc:
- case Key.ControlC:
- //TODO: Running = false;
- break;
- default:
- var key = kb.KeyValue;
- if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9')) {
- char c = Char.ToUpper ((char)key);
- if (Menus [selected].Children == null)
- return false;
- foreach (var mi in Menus [selected].Children) {
- int p = mi.Title.IndexOf ('_');
- if (p != -1 && p + 1 < mi.Title.Length) {
- if (mi.Title [p + 1] == c) {
- Selected (mi);
- return true;
- }
- }
- }
- }
- return false;
- }
- SetNeedsDisplay ();
- return true;
- }
- }
- }
|