diff --git a/Core.cs b/Core.cs
index 750189085..82e3246cd 100644
--- a/Core.cs
+++ b/Core.cs
@@ -15,6 +15,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Threading;
namespace Terminal {
@@ -808,6 +809,35 @@ namespace Terminal {
throw new NotImplementedException ();
}
+ class MainLoopSyncContext : SynchronizationContext {
+ Mono.Terminal.MainLoop mainLoop;
+
+ public MainLoopSyncContext (Mono.Terminal.MainLoop mainLoop)
+ {
+ this.mainLoop = mainLoop;
+ }
+
+ public override SynchronizationContext CreateCopy ()
+ {
+ return new MainLoopSyncContext (MainLoop);
+ }
+
+ public override void Post (SendOrPostCallback d, object state)
+ {
+ mainLoop.AddIdle (() => {
+ d (state);
+ return false;
+ });
+ }
+
+ public override void Send (SendOrPostCallback d, object state)
+ {
+ mainLoop.Invoke (() => {
+ d (state);
+ });
+ }
+ }
+
///
/// Initializes the Application
///
@@ -818,6 +848,7 @@ namespace Terminal {
Driver.Init (TerminalResized);
MainLoop = new Mono.Terminal.MainLoop ();
+ SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
Top = Toplevel.Create ();
focus = Top;
}
diff --git a/Views/Menu.cs b/Views/Menu.cs
index 6a5465fae..7a3514c40 100644
--- a/Views/Menu.cs
+++ b/Views/Menu.cs
@@ -5,10 +5,9 @@
// Miguel de Icaza (miguel@gnome.org)
//
// TODO:
-// Add accelerator support (ShortCut in MenuItem)
+// Add accelerator support, but should also support chords (ShortCut in MenuItem)
// Add mouse support
// Allow menus inside menus
-// Handle actual activation
using System;
namespace Terminal {
@@ -55,29 +54,33 @@ namespace Terminal {
public class MenuBarItem {
public MenuBarItem (string title, MenuItem [] children)
{
- Title = title ?? "";
+ SetTitle (title ?? "");
Children = children;
}
+ void SetTitle (string title)
+ {
+ if (title == null)
+ title = "";
+ Title = title;
+ int len = 0;
+ foreach (var ch in Title) {
+ if (ch == '_')
+ continue;
+ len++;
+ }
+ TitleLength = len;
+ }
+
public string Title { get; set; }
public MenuItem [] Children { get; set; }
- public int Current { get; set; }
- internal int TitleLength {
- get {
- int len = 0;
- foreach (var ch in Title) {
- if (ch == '_')
- continue;
- len++;
- }
- return len;
- }
- }
+ internal int TitleLength { get; private set; }
}
class Menu : View {
MenuBarItem barItems;
MenuBar host;
+ int current;
static Rect MakeFrame (int x, int y, MenuItem [] items)
{
@@ -106,7 +109,7 @@ namespace Terminal {
for (int i = 0; i < barItems.Children.Length; i++){
var item = barItems.Children [i];
Move (1, i+1);
- Driver.SetAttribute (item == null ? Colors.Base.Focus : i == barItems.Current ? Colors.Menu.Focus : Colors.Menu.Normal);
+ Driver.SetAttribute (item == null ? Colors.Base.Focus : i == current ? Colors.Menu.Focus : Colors.Menu.Normal);
for (int p = 0; p < Frame.Width-2; p++)
if (item == null)
Driver.AddSpecial (SpecialChar.HLine);
@@ -118,8 +121,8 @@ namespace Terminal {
Move (2, i + 1);
DrawHotString (item.Title,
- i == barItems.Current ? Colors.Menu.HotFocus : Colors.Menu.HotNormal,
- i == barItems.Current ? Colors.Menu.Focus : Colors.Menu.Normal);
+ i == current? Colors.Menu.HotFocus : Colors.Menu.HotNormal,
+ i == current ? Colors.Menu.Focus : Colors.Menu.Normal);
// The help string
var l = item.Help.Length;
@@ -130,22 +133,33 @@ namespace Terminal {
public override void PositionCursor ()
{
- Move (2, 1 + barItems.Current);
+ Move (2, 1 + current);
+ }
+
+ void Run (Action action)
+ {
+ if (action == null)
+ return;
+
+ Application.MainLoop.AddIdle (() => {
+ action ();
+ return false;
+ });
}
public override bool ProcessKey (KeyEvent kb)
{
switch (kb.Key) {
case Key.CursorUp:
- barItems.Current--;
- if (barItems.Current < 0)
- barItems.Current = barItems.Children.Length - 1;
+ current--;
+ if (current < 0)
+ current = barItems.Children.Length - 1;
SetNeedsDisplay ();
break;
case Key.CursorDown:
- barItems.Current++;
- if (barItems.Current == barItems.Children.Length)
- barItems.Current = 0;
+ current++;
+ if (current== barItems.Children.Length)
+ current = 0;
SetNeedsDisplay ();
break;
case Key.CursorLeft:
@@ -157,6 +171,24 @@ namespace Terminal {
case Key.Esc:
host.CloseMenu ();
break;
+ case Key.Enter:
+ host.CloseMenu ();
+ Run (barItems.Children [current].Action);
+ break;
+ default:
+ // TODO: rune-ify
+ if (Char.IsLetterOrDigit ((char)kb.KeyValue)) {
+ var x = Char.ToUpper ((char)kb.KeyValue);
+
+ foreach (var item in barItems.Children) {
+ if (item.HotKey == x) {
+ host.CloseMenu ();
+ Run (item.Action);
+ return true;
+ }
+ }
+ }
+ break;
}
return true;
}
@@ -177,28 +209,6 @@ namespace Terminal {
selected = -1;
}
- ///
- /// Activates the menubar
- ///
- 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 ();
- }
-
public override void Redraw (Rect region)
{
Move (0, 0);
@@ -312,38 +322,14 @@ namespace Terminal {
StartMenu ();
return true;
}
+ var kc = kb.KeyValue;
+
return base.ProcessHotKey (kb);
}
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)
@@ -353,13 +339,6 @@ namespace Terminal {
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;
diff --git a/demo.cs b/demo.cs
index 136b764ee..8dd460ca0 100644
--- a/demo.cs
+++ b/demo.cs
@@ -33,7 +33,7 @@ class Demo {
var win = new Window (new Rect (0, 1, tframe.Width, tframe.Height-1), "Hello");
var menu = new MenuBar (new MenuBarItem [] {
new MenuBarItem ("_File", new MenuItem [] {
- new MenuItem ("_New", "Creates new file", null),
+ new MenuItem ("_New", "Creates new file", () => System.Console.WriteLine ("foo")),
new MenuItem ("_Open", "", null),
new MenuItem ("_Close", "", null),
new MenuItem ("_Quit", "", null)