Some work on activation

This commit is contained in:
Miguel de Icaza
2018-01-06 16:39:18 -05:00
parent 0e12d02f5d
commit 01848bc5ee
3 changed files with 91 additions and 81 deletions

31
Core.cs
View File

@@ -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);
});
}
}
/// <summary>
/// Initializes the Application
/// </summary>
@@ -818,6 +848,7 @@ namespace Terminal {
Driver.Init (TerminalResized);
MainLoop = new Mono.Terminal.MainLoop ();
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
Top = Toplevel.Create ();
focus = Top;
}

View File

@@ -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;
}
/// <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 ();
}
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;

View File

@@ -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)