123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- using System.IO;
- using System.Text;
- using Terminal.Gui;
- namespace UICatalog.Scenarios;
- [ScenarioMetadata ("HexEditor", "A binary (hex) editor using the HexView control.")]
- [ScenarioCategory ("Controls")]
- [ScenarioCategory ("Dialogs")]
- [ScenarioCategory ("Text and Formatting")]
- [ScenarioCategory ("Overlapped")]
- [ScenarioCategory ("Files and IO")]
- public class HexEditor : Scenario
- {
- private string _fileName = "demo.bin";
- private HexView _hexView;
- private MenuItem _miAllowEdits;
- private bool _saved = true;
- private Shortcut _scAddress;
- private Shortcut _scInfo;
- private Shortcut _scPosition;
- private StatusBar _statusBar;
- public override void Main ()
- {
- Application.Init ();
- var app = new Toplevel
- {
- ColorScheme = Colors.ColorSchemes ["Base"]
- };
- CreateDemoFile (_fileName);
- _hexView = new (new MemoryStream (Encoding.UTF8.GetBytes ("Demo text.")))
- {
- X = 0,
- Y = 1,
- Width = Dim.Fill (),
- Height = Dim.Fill (1),
- Title = _fileName ?? "Untitled",
- BorderStyle = LineStyle.Rounded
- };
- _hexView.Edited += _hexView_Edited;
- _hexView.PositionChanged += _hexView_PositionChanged;
- app.Add (_hexView);
- var menu = new MenuBar
- {
- Menus =
- [
- new (
- "_File",
- new MenuItem []
- {
- new ("_New", "", () => New ()),
- new ("_Open", "", () => Open ()),
- new ("_Save", "", () => Save ()),
- null,
- new ("_Quit", "", () => Quit ())
- }
- ),
- new (
- "_Edit",
- new MenuItem []
- {
- new ("_Copy", "", () => Copy ()),
- new ("C_ut", "", () => Cut ()),
- new ("_Paste", "", () => Paste ())
- }
- ),
- new (
- "_Options",
- new []
- {
- _miAllowEdits = new (
- "_AllowEdits",
- "",
- () => ToggleAllowEdits ()
- )
- {
- Checked = _hexView.AllowEdits,
- CheckType = MenuItemCheckStyle
- .Checked
- }
- }
- )
- ]
- };
- app.Add (menu);
- var addressWidthUpDown = new NumericUpDown
- {
- Value = _hexView.AddressWidth
- };
- NumericUpDown<long> addressUpDown = new NumericUpDown<long>
- {
- Value = _hexView.Address,
- Format = $"0x{{0:X{_hexView.AddressWidth}}}"
- };
- addressWidthUpDown.ValueChanging += (sender, args) =>
- {
- args.Cancel = args.NewValue is < 0 or > 8;
- if (!args.Cancel)
- {
- _hexView.AddressWidth = args.NewValue;
- // ReSharper disable once AccessToDisposedClosure
- addressUpDown.Format = $"0x{{0:X{_hexView.AddressWidth}}}";
- }
- };
- addressUpDown.ValueChanging += (sender, args) =>
- {
- args.Cancel = args.NewValue is < 0;
- if (!args.Cancel)
- {
- _hexView.Address = args.NewValue;
- }
- };
- _statusBar = new (
- [
- new (Key.F2, "Open", Open),
- new (Key.F3, "Save", Save),
- new ()
- {
- CommandView = addressWidthUpDown,
- HelpText = "Address Width"
- },
- _scAddress = new ()
- {
- CommandView = addressUpDown,
- HelpText = "Address:"
- },
- _scInfo = new (Key.Empty, string.Empty, () => { }),
- _scPosition = new (Key.Empty, string.Empty, () => { })
- ])
- {
- AlignmentModes = AlignmentModes.IgnoreFirstOrLast
- };
- app.Add (_statusBar);
- _hexView.Source = LoadFile ();
- Application.Run (app);
- addressUpDown.Dispose ();
- addressWidthUpDown.Dispose ();
- app.Dispose ();
- Application.Shutdown ();
- }
- private void _hexView_Edited (object sender, HexViewEditEventArgs e) { _saved = false; }
- private void _hexView_PositionChanged (object sender, HexViewEventArgs obj)
- {
- _scInfo.Title =
- $"Bytes: {_hexView.Source!.Length}";
- _scPosition.Title =
- $"L: {obj.CursorPosition.Y} C: {obj.CursorPosition.X} Per Line: {obj.BytesPerLine}";
- if (_scAddress.CommandView is NumericUpDown<long> addrNumericUpDown)
- {
- addrNumericUpDown.Value = obj.Address;
- }
- }
- private void Copy () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok"); }
- private void CreateDemoFile (string fileName)
- {
- var sb = new StringBuilder ();
- sb.Append ("Hello world.\n");
- sb.Append ("This is a test of the Emergency Broadcast System.\n");
- StreamWriter sw = File.CreateText (fileName);
- sw.Write (sb.ToString ());
- sw.Close ();
- }
- private void CreateUnicodeDemoFile (string fileName)
- {
- var sb = new StringBuilder ();
- sb.Append ("Hello world with wide codepoints: 𝔹Aℝ𝔽.\n");
- sb.Append ("This is a test of the Emergency Broadcast System.\n");
- byte [] buffer = Encoding.Unicode.GetBytes (sb.ToString ());
- var ms = new MemoryStream (buffer);
- var file = new FileStream (fileName, FileMode.Create, FileAccess.Write);
- ms.WriteTo (file);
- file.Close ();
- ms.Close ();
- }
- private void Cut () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok"); }
- private Stream LoadFile ()
- {
- var stream = new MemoryStream ();
- if (!_saved && _hexView.Edits.Count > 0)
- {
- if (MessageBox.ErrorQuery (
- "Save",
- "The changes were not saved. Want to open without saving?",
- "_Yes",
- "_No"
- )
- == 1)
- {
- return _hexView.Source;
- }
- _hexView.DiscardEdits ();
- _saved = true;
- }
- if (_fileName != null)
- {
- byte [] bin = File.ReadAllBytes (_fileName);
- stream.Write (bin);
- _hexView.Title = _fileName;
- _saved = true;
- }
- else
- {
- _hexView.Title = _fileName ?? "Untitled";
- }
- return stream;
- }
- private void New ()
- {
- _fileName = null;
- _hexView.Source = LoadFile ();
- }
- private void Open ()
- {
- var d = new OpenDialog { Title = "Open", AllowsMultipleSelection = false };
- Application.Run (d);
- if (!d.Canceled)
- {
- _fileName = d.FilePaths [0];
- _hexView.Source = LoadFile ();
- _hexView.DisplayStart = 0;
- }
- d.Dispose ();
- }
- private void Paste () { MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "_Ok"); }
- private void Quit () { Application.RequestStop (); }
- private void Save ()
- {
- if (_fileName != null)
- {
- using (var fs = new FileStream (_fileName, FileMode.OpenOrCreate))
- {
- _hexView.ApplyEdits (fs);
- //_hexView.Source.Position = 0;
- //_hexView.Source.CopyTo (fs);
- //fs.Flush ();
- }
- _saved = true;
- }
- else
- {
- _hexView.ApplyEdits ();
- }
- }
- private void ToggleAllowEdits () { _hexView.AllowEdits = (bool)(_miAllowEdits.Checked = !_miAllowEdits.Checked); }
- }
|