From 263de03914a3de5d55c4508c322e32d36caf2a87 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bruyère Date: Mon, 7 Jun 2021 15:05:30 +0200 Subject: suggestion in IML editor, editor base classe for ShowCase and LogAnalyzer --- Samples/common/src/SampleBaseForEditor.cs | 312 ++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 Samples/common/src/SampleBaseForEditor.cs (limited to 'Samples/common/src/SampleBaseForEditor.cs') diff --git a/Samples/common/src/SampleBaseForEditor.cs b/Samples/common/src/SampleBaseForEditor.cs new file mode 100644 index 00000000..4af718a2 --- /dev/null +++ b/Samples/common/src/SampleBaseForEditor.cs @@ -0,0 +1,312 @@ +// Copyright (c) 2013-2021 Bruyère Jean-Philippe +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using Crow; +using System.IO; +using System.Text; +using Crow.IML; +using System.Runtime.CompilerServices; +using Glfw; +using System.Diagnostics; +using Crow.Text; +using System.Collections.Generic; +using Encoding = System.Text.Encoding; + +namespace Samples +{ + public class SampleBaseForEditor : SampleBase + { + public static SampleBaseForEditor CurrentProgramInstance; + + protected override void OnInitialized () { + initCommands (); + + base.OnInitialized (); + + if (string.IsNullOrEmpty (CurrentDir)) + CurrentDir = Path.Combine (Directory.GetCurrentDirectory (), "Interfaces"); + + } + + protected const string _defaultFileName = "unnamed.txt"; + protected string source = "", origSource; + protected TextBox editor; + bool debugLogRecording; + + + public string CurrentDir { + get => Configuration.Global.Get (nameof (CurrentDir)); + set { + if (CurrentDir == value) + return; + Configuration.Global.Set (nameof (CurrentDir), value); + NotifyValueChanged (CurrentDir); + } + } + public string CurrentFile { + get => Configuration.Global.Get (nameof (CurrentFile)); + set { + if (CurrentFile == value) + return; + Configuration.Global.Set (nameof (CurrentFile), value); + NotifyValueChanged (CurrentFile); + } + } + public virtual string Source { + get => source; + set { + if (source == value) + return; + source = value; + CMDSave.CanExecute = IsDirty; + NotifyValueChanged (source); + NotifyValueChanged ("IsDirty", IsDirty); + } + } + public bool DebugLoggingEnabled => DbgLogger.IsEnabled; + + public DbgEvtType RecordedEvents { + get => Configuration.Global.Get (nameof (RecordedEvents)); + set { + if (RecordedEvents == value) + return; + Configuration.Global.Set (nameof (RecordedEvents), value); + if (DebugLogRecording) + DbgLogger.IncludeEvents = RecordedEvents; + NotifyValueChanged(RecordedEvents); + } + } + public DbgEvtType DiscardedEvents { + get => Configuration.Global.Get (nameof (DiscardedEvents)); + set { + if (DiscardedEvents == value) + return; + Configuration.Global.Set (nameof (DiscardedEvents), value); + if (DebugLogRecording) + DbgLogger.DiscardEvents = DiscardedEvents; + NotifyValueChanged(DiscardedEvents); + } + } + public bool DebugLogRecording { + get => debugLogRecording; + set { + if (debugLogRecording == value) + return; + debugLogRecording = value; + NotifyValueChanged(debugLogRecording); + } + } + + public new bool IsDirty => source != origSource; + + + public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit, CMDShowLeftPane, + CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions; + public CommandGroup EditorCommands => new CommandGroup (CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDSave, CMDSaveAs); + protected virtual void initCommands () + { + CMDNew = new Command ("New", new Action (onNewFile), "#Icons.blank-file.svg"); + CMDSave = new Command ("Save", new Action (onSave), "#Icons.save.svg", false); + CMDSaveAs = new Command ("Save As...", new Action (onSaveAs), "#Icons.save.svg"); + CMDQuit = new Command ("Quit", new Action (() => base.Quit ()), "#Icons.exit.svg"); + CMDUndo = new Command ("Undo", new Action (undo),"#Icons.undo.svg", false); + CMDRedo = new Command ("Redo", new Action (redo),"#Icons.redo.svg", false); + CMDCut = new Command ("Cut", new Action (cut), "#Icons.scissors.svg", false); + CMDCopy = new Command ("Copy", new Action (copy), "#Icons.copy-file.svg", false); + CMDPaste= new Command ("Paste", new Action (paste), "#Icons.paste-on-document.svg", false); + } + + + protected Stack undoStack = new Stack (); + protected Stack redoStack = new Stack (); + protected TextSpan selection; + protected string SelectedText => + selection.IsEmpty ? "" : Source.AsSpan (selection.Start, selection.Length).ToString (); + + protected void undo () { + if (undoStack.TryPop (out TextChange tch)) { + redoStack.Push (tch.Inverse (source)); + CMDRedo.CanExecute = true; + apply (tch); + editor.SetCursorPosition (tch.End + tch.ChangedText.Length); + } + if (undoStack.Count == 0) + CMDUndo.CanExecute = false; + } + protected void redo () { + if (redoStack.TryPop (out TextChange tch)) { + undoStack.Push (tch.Inverse (source)); + CMDUndo.CanExecute = true; + apply (tch); + editor.SetCursorPosition (tch.End + tch.ChangedText.Length); + } + if (redoStack.Count == 0) + CMDRedo.CanExecute = false; + } + protected void resetUndoRedo () { + undoStack.Clear (); + redoStack.Clear (); + CMDUndo.CanExecute = false; + CMDRedo.CanExecute = false; + } + + protected void cut () { + copy (); + applyChange (new TextChange (selection.Start, selection.Length, "")); + } + protected void copy () { + Clipboard = SelectedText; + } + protected void paste () { + applyChange (new TextChange (selection.Start, selection.Length, Clipboard)); + } + protected void onNewFile () { + if (IsDirty) { + MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?").Yes += (sender, e) => newFile (); + } else + newFile (); + } + protected void onSave () + { + if (!File.Exists (CurrentFile)) { + onSaveAs (); + return; + } + save (); + } + protected void onSaveAs () + { + string dir = Path.GetDirectoryName (CurrentFile); + if (string.IsNullOrEmpty (dir)) + dir = Directory.GetCurrentDirectory (); + LoadIMLFragment (@"").DataSource = this; + } + protected void saveFileDialog_OkClicked (object sender, EventArgs e) + { + FileDialog fd = sender as FileDialog; + + if (string.IsNullOrEmpty (fd.SelectedFileFullPath)) + return; + + if (File.Exists(fd.SelectedFileFullPath)) { + MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "File exists, overwrite?"); + mb.Yes += (sender2, e2) => { + CurrentFile = fd.SelectedFileFullPath; + save (); + }; + return; + } + + CurrentFile = fd.SelectedFileFullPath; + save (); + } + + protected void newFile() + { + disableTextChangedEvent = true; + Source = @"