Skip to content

Commit edbc181

Browse files
authored
Merge pull request #311 from gui-cs/keybindings-fix
Adds keybindings configuration window
2 parents e32b44c + fd5bd9b commit edbc181

6 files changed

Lines changed: 316 additions & 12 deletions

File tree

src/Design.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public class Design
3838
typeof(TabView),
3939
typeof(Window),
4040
typeof(Toplevel),
41-
typeof(View),
4241
typeof(GraphView),
4342
typeof(HexView),
4443
typeof(LineView),

src/UI/Editor.cs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.ObjectModel;
22
using System.Reflection;
33
using System.Text;
4+
using System.Text.Json;
45
using Microsoft.Extensions.Configuration;
56
using Microsoft.Extensions.Logging;
67
using Serilog;
@@ -21,7 +22,7 @@ namespace TerminalGuiDesigner.UI;
2122
/// </summary>
2223
public class Editor : Toplevel
2324
{
24-
private readonly KeyMap keyMap;
25+
private KeyMap keyMap;
2526
private readonly KeyboardManager keyboardManager;
2627
private readonly MouseManager mouseManager;
2728

@@ -46,6 +47,7 @@ public class Editor : Toplevel
4647
/// </summary>
4748
internal Guid? LastSavedOperation;
4849

50+
private static string _keymapPath = string.Empty;
4951
private static string _logDirectory = string.Empty;
5052

5153
/// <summary>
@@ -66,9 +68,32 @@ public Editor()
6668
Logging.Logger = CreateLogger();
6769
}
6870

71+
LoadKeyMap();
72+
73+
this.keyboardManager = new KeyboardManager(this.keyMap);
74+
this.mouseManager = new MouseManager();
75+
this.Closing += this.Editor_Closing;
76+
77+
this.BuildRootMenu();
78+
}
79+
80+
private void LoadKeyMap()
81+
{
82+
_keymapPath = Path.Combine(
83+
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
84+
"TerminalGuiDesigner", "keymap.json");
85+
6986
try
7087
{
71-
this.keyMap = new ConfigurationBuilder( ).AddYamlFile( "Keys.yaml", true ).Build( ).Get<KeyMap>( ) ?? new( );
88+
if (File.Exists(_keymapPath))
89+
{
90+
var json = File.ReadAllText(_keymapPath);
91+
this.keyMap = JsonSerializer.Deserialize<KeyMap>(json) ?? new KeyMap();
92+
}
93+
else
94+
{
95+
this.keyMap = new KeyMap();
96+
}
7297

7398
SelectionManager.Instance.SelectedScheme = this.keyMap.SelectionColor.Scheme;
7499
}
@@ -78,12 +103,21 @@ public Editor()
78103
ExceptionViewer.ShowException("Failed to read keybindings from configuration file", ex);
79104
this.keyMap = new KeyMap();
80105
}
106+
}
81107

82-
this.keyboardManager = new KeyboardManager(this.keyMap);
83-
this.mouseManager = new MouseManager();
84-
this.Closing += this.Editor_Closing;
85108

86-
this.BuildRootMenu();
109+
private void SaveKeyMap()
110+
{
111+
try
112+
{
113+
var json = JsonSerializer.Serialize(this.keyMap);
114+
File.WriteAllText(_keymapPath, json);
115+
SelectionManager.Instance.SelectedScheme = this.keyMap.SelectionColor.Scheme;
116+
}
117+
catch (Exception ex)
118+
{
119+
ExceptionViewer.ShowException("Failed to save keybindings from configuration file", ex);
120+
}
87121
}
88122

89123
static ILogger CreateLogger()
@@ -769,6 +803,7 @@ private void BuildRootMenu()
769803
$"{this.keyMap.ShowHelp} - Show Help",
770804
$"{this.keyMap.New} - New Window/Class",
771805
$"{this.keyMap.Open} - Open a .Designer.cs file",
806+
$"Keybindings",
772807
};
773808

774809
// center all the commands
@@ -783,7 +818,7 @@ private void BuildRootMenu()
783818
X = Pos.Center(),
784819
Y = Pos.Percent(75),
785820
Width = maxWidth,
786-
Height = 3,
821+
Height = 4,
787822
ColorScheme = new ColorScheme
788823
(
789824
new Attribute(new Color(Color.White),new Color(Color.Black)),
@@ -813,6 +848,9 @@ private void BuildRootMenu()
813848
case 2:
814849
this.Open();
815850
break;
851+
case 3:
852+
this.ChangeKeybindings();
853+
break;
816854
}
817855
}
818856

@@ -836,6 +874,18 @@ private void BuildRootMenu()
836874
this.Add(this.rootCommandsListView);
837875
}
838876

877+
private void ChangeKeybindings()
878+
{
879+
var kb = new KeyBindingsUI(keyMap);
880+
Application.Run(kb);
881+
882+
if (kb.Save)
883+
{
884+
SaveKeyMap();
885+
}
886+
}
887+
888+
839889
private void Editor_Closing(object? sender, ToplevelClosingEventArgs obj)
840890
{
841891
if (this.viewBeingEdited == null)

src/UI/Windows/KeyBindingsUI.Designer.cs

Lines changed: 151 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/UI/Windows/KeyBindingsUI.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
2+
//------------------------------------------------------------------------------
3+
4+
// <auto-generated>
5+
// This code was generated by:
6+
// TerminalGuiDesigner v2.0.0.0
7+
// You can make changes to this file and they will not be overwritten when saving.
8+
// </auto-generated>
9+
// -----------------------------------------------------------------------------
10+
11+
using System.Reflection;
12+
using System.Text.Json;
13+
14+
namespace TerminalGuiDesigner.UI.Windows {
15+
using Terminal.Gui;
16+
17+
18+
public partial class KeyBindingsUI {
19+
private readonly KeyMap keyMap;
20+
private readonly PropertyInfo[] _props;
21+
22+
public bool Save { get; set; } = false;
23+
24+
public KeyBindingsUI(KeyMap keyMap) {
25+
this.keyMap = keyMap;
26+
InitializeComponent();
27+
28+
_props = typeof(KeyMap).GetProperties()
29+
.Where(p=>p.PropertyType == typeof(string))
30+
.OrderBy(p=>p.Name)
31+
.ToArray();
32+
33+
tableView.Table = new EnumerableTableSource<PropertyInfo>(_props,
34+
new Dictionary<string, Func<PropertyInfo, object>>()
35+
{
36+
{ "Function", p => p.Name },
37+
{ "Key", p => p.GetValue(this.keyMap) }
38+
});
39+
40+
var keyStyle = tableView.Style.GetOrCreateColumnStyle(1);
41+
42+
var badCellColor = CloneColorSchemeButMake(tableView.ColorScheme,Color.Red);
43+
44+
keyStyle.ColorGetter = (k) =>
45+
{
46+
var val = _props[k.RowIndex].GetValue(this.keyMap);
47+
var matches = _props.Select(k => k.GetValue(this.keyMap)).Count(v => Equals(v,val));
48+
if (matches > 1)
49+
{
50+
return badCellColor;
51+
}
52+
53+
// Use normal color scheme
54+
return null;
55+
};
56+
57+
tableView.CellActivated += (s, e) =>
58+
{
59+
var prop = _props[e.Row];
60+
var k = Modals.GetShortcut();
61+
prop.SetValue(this.keyMap,k.ToString());
62+
this.SetNeedsDraw();
63+
};
64+
btnReset.Accepting += (s, e) =>
65+
{
66+
var defaultMap = new KeyMap();
67+
foreach (var p in _props)
68+
{
69+
var def = p.GetValue(defaultMap);
70+
p.SetValue(this.keyMap, def);
71+
this.SetNeedsDraw();
72+
}
73+
};
74+
75+
btnSave.Accepting += (s, e) =>
76+
{
77+
Save = true;
78+
e.Cancel = true;
79+
Application.RequestStop();
80+
};
81+
btnCancel.Accepting += (s, e) =>
82+
{
83+
e.Cancel = true;
84+
Application.RequestStop();
85+
};
86+
}
87+
88+
private ColorScheme CloneColorSchemeButMake(ColorScheme cs,Color color)
89+
{
90+
return new ColorScheme
91+
{
92+
Disabled = cs.Disabled,
93+
Focus = cs.Focus,
94+
HotFocus = cs.HotFocus,
95+
HotNormal = cs.HotNormal,
96+
Normal = new Attribute(color, cs.Normal.Background)
97+
};
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)