diff --git a/Editor/App.config b/Editor/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/Editor/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Editor/ConsoleControl.cs b/Editor/ConsoleControl.cs new file mode 100644 index 0000000..b36809f --- /dev/null +++ b/Editor/ConsoleControl.cs @@ -0,0 +1,59 @@ +using KCore; +using KCore.Graphics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Editor +{ + public class ConsoleControl : Form + { + private object sync = new object(); + public static ConsoleRequestPack ConsoleThreadRequest; + public static ConsoleRequestPack MainFormThreadRequest; + public static bool RequestSended; + + public ConsoleControl() : base() + { + AllowedDashboard = false; + Bind(new DelegateRequest(this, form => true, form => + { + Program.GetWindowRect(Program.ConsoleHandler, ref Program.ConsoleRect); + Program.MainForm.MoveRequest = true; + })); + Bind(new DelegateRequest(this, form => RequestSended, form => + { + lock (sync) ConsoleThreadRequest = MainFormThreadRequest; + RequestSended = false; + })); + Bind(new DelegateRequest(this, form => + { + lock (sync) return ConsoleThreadRequest != null; + }, form => + { + lock (sync) + { + ConsoleThreadRequest.Invoke(); + ConsoleThreadRequest = null; + } + })); + } + + protected override void OnOpening() + { + while (Program.MainForm == null) + Thread.Sleep(100); + } + + protected override void OnKeyDown(byte key) + { + if (key == 1) + if (Program.MainForm != null) + Program.MainForm.ClickRequest = true; + } + } +} diff --git a/Editor/ConsoleRequestPack.cs b/Editor/ConsoleRequestPack.cs new file mode 100644 index 0000000..b4b9ae5 --- /dev/null +++ b/Editor/ConsoleRequestPack.cs @@ -0,0 +1,29 @@ +using KCore.Graphics.Widgets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Editor +{ + public abstract class ConsoleRequestPack + { + public abstract void Invoke(); + public void Send() + { + ConsoleControl.MainFormThreadRequest = this; + ConsoleControl.RequestSended = true; + } + } + + public class SimpleRequest : ConsoleRequestPack + { + public SimpleRequest(Action action) => Action = action; + public Action Action { get; set; } + public override void Invoke() + { + Action.Invoke(); + } + } +} diff --git a/Editor/Editor.csproj b/Editor/Editor.csproj new file mode 100644 index 0000000..7d03507 --- /dev/null +++ b/Editor/Editor.csproj @@ -0,0 +1,97 @@ + + + + + Debug + AnyCPU + {7450C379-DD7C-410E-A122-A96EF8082F37} + Exe + Editor + Editor + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + ..\bin\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + ..\bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {FE2FBEFB-28CC-4928-B11B-D22BD7DFE137} + KCore + + + + + ../building/IncEditorRevision.bat + + \ No newline at end of file diff --git a/Editor/MainForm.Designer.cs b/Editor/MainForm.Designer.cs new file mode 100644 index 0000000..7dc0f87 --- /dev/null +++ b/Editor/MainForm.Designer.cs @@ -0,0 +1,138 @@ +namespace Editor +{ + partial class MainForm + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором форм Windows + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.CurrentPositionLabel = new System.Windows.Forms.Label(); + this.RequestChecker = new System.Windows.Forms.Timer(this.components); + this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.button3 = new System.Windows.Forms.Button(); + this.button4 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // CurrentPositionLabel + // + this.CurrentPositionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CurrentPositionLabel.Font = new System.Drawing.Font("Lucida Console", 20F); + this.CurrentPositionLabel.Location = new System.Drawing.Point(11, 9); + this.CurrentPositionLabel.Name = "CurrentPositionLabel"; + this.CurrentPositionLabel.Size = new System.Drawing.Size(261, 31); + this.CurrentPositionLabel.TabIndex = 0; + this.CurrentPositionLabel.Text = "--- --"; + this.CurrentPositionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // RequestChecker + // + this.RequestChecker.Enabled = true; + this.RequestChecker.Interval = 16; + this.RequestChecker.Tick += new System.EventHandler(this.timer1_Tick); + // + // button2 + // + this.button2.BackColor = System.Drawing.Color.Black; + this.button2.Cursor = System.Windows.Forms.Cursors.Hand; + this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button2.Font = new System.Drawing.Font("Lucida Console", 20F); + this.button2.ForeColor = System.Drawing.Color.White; + this.button2.Location = new System.Drawing.Point(166, 443); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(50, 50); + this.button2.TabIndex = 2; + this.button2.TabStop = false; + this.button2.Text = "A"; + this.button2.UseVisualStyleBackColor = false; + // + // button1 + // + this.button1.BackColor = System.Drawing.Color.White; + this.button1.Cursor = System.Windows.Forms.Cursors.Hand; + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button1.Font = new System.Drawing.Font("Lucida Console", 20F); + this.button1.ForeColor = System.Drawing.Color.Black; + this.button1.Location = new System.Drawing.Point(222, 499); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(50, 50); + this.button1.TabIndex = 3; + this.button1.TabStop = false; + this.button1.Text = "B"; + this.button1.UseVisualStyleBackColor = false; + // + // button3 + // + this.button3.Location = new System.Drawing.Point(182, 499); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(34, 23); + this.button3.TabIndex = 4; + this.button3.Text = "dfl"; + this.button3.UseVisualStyleBackColor = true; + // + // button4 + // + this.button4.Location = new System.Drawing.Point(222, 470); + this.button4.Name = "button4"; + this.button4.Size = new System.Drawing.Size(34, 23); + this.button4.TabIndex = 5; + this.button4.Text = "swp"; + this.button4.UseVisualStyleBackColor = true; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 561); + this.ControlBox = false; + this.Controls.Add(this.button4); + this.Controls.Add(this.button3); + this.Controls.Add(this.button2); + this.Controls.Add(this.button1); + this.Controls.Add(this.CurrentPositionLabel); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "MainForm"; + this.ShowIcon = false; + this.Text = "KCore Editor"; + this.TopMost = true; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label CurrentPositionLabel; + private System.Windows.Forms.Timer RequestChecker; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.Button button4; + } +} + diff --git a/Editor/MainForm.cs b/Editor/MainForm.cs new file mode 100644 index 0000000..293a1ea --- /dev/null +++ b/Editor/MainForm.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Editor +{ + public partial class MainForm : Form + { + public bool ClickRequest, MoveRequest; + + public int GetTopWithout() + { + return Program.ConsoleRect.Bottom - KCore.Terminal.FixedWindowHeight * Program.PixelSize.Item2; + } + public bool In(Point pos, int top_without) + { + return pos.X >= Program.ConsoleRect.Left && pos.X <= Program.ConsoleRect.Right && pos.Y >= top_without && pos.Y <= Program.ConsoleRect.Bottom; + } + public (int, int) GetConsolePosition(Point pos, int top_without) + { + var left = (pos.X - Program.ConsoleRect.Left - Program.Offset.Item1) / Program.PixelSize.Item1; + var top = (pos.Y - top_without - Program.Offset.Item2) / Program.PixelSize.Item2; + return (left, top); + } + + public void ConsoleMouseMoveHandler() + { + MoveRequest = false; + var pos = Cursor.Position; + var top_without = GetTopWithout(); + if (In(pos, top_without)) + { + var (left, top) = GetConsolePosition(pos, top_without); + CurrentPositionLabel.Text = $"{left,-3} {top}"; + } + } + public void ConsoleMouseClickHandler() + { + ClickRequest = false; + var pos = Cursor.Position; + var top_without = GetTopWithout(); + + if (!In(pos, top_without)) + { + return; + } + var (left, top) = GetConsolePosition(pos, top_without); + CurrentPositionLabel.Text = $"{left,-3} {top}"; + new SimpleRequest(() => + { + KCore.Terminal.Back = KCore.Theme.Fore; + KCore.Terminal.Set(left, top); + KCore.Terminal.Write('-'); + }).Send(); + } + + private void timer1_Tick(object sender, EventArgs e) + { + if (ClickRequest) ConsoleMouseClickHandler(); + if (MoveRequest) ConsoleMouseMoveHandler(); + } + + public MainForm() + { + InitializeComponent(); + } + } +} diff --git a/Editor/MainForm.resx b/Editor/MainForm.resx new file mode 100644 index 0000000..282eb44 --- /dev/null +++ b/Editor/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Editor/Program.cs b/Editor/Program.cs new file mode 100644 index 0000000..36c7acf --- /dev/null +++ b/Editor/Program.cs @@ -0,0 +1,81 @@ +using KCore; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Editor +{ + internal static class Program + { + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr FindWindow(string strClassName, string strWindowName); + + [DllImport("user32.dll")] + public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); + + public struct Rect + { + public int Left { get; set; } + public int Top { get; set; } + public int Right { get; set; } + public int Bottom { get; set; } + } + + public static MainForm MainForm; + public static ConsoleControl ConsoleControl; + public static IntPtr ConsoleHandler; + public static Rect ConsoleRect; + + public static bool NeedRestart = false; + public static readonly (int, int) PixelSize = (12, 20); + public static (int, int) Offset = (8, -6); + + /// + /// Главная точка входа для приложения. + /// + [STAThread] + static void Main() + { + var full_path = Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName.Replace('\\', '_'); + var console = Registry.CurrentUser.OpenSubKey("Console", true); + var editor = console.OpenSubKey(full_path); + if (editor == null) + { + editor = console.CreateSubKey(full_path); + NeedRestart = true; + editor.SetValue("QuickEdit", 0, RegistryValueKind.DWord); + editor.SetValue("LineSelection", 0, RegistryValueKind.DWord); + editor.SetValue("CursorType", 0, RegistryValueKind.DWord); + editor.SetValue("FaceName", "Lucida Console", RegistryValueKind.String); + editor.SetValue("FontFamily", 54, RegistryValueKind.DWord); + editor.SetValue("FontSize", 1310720, RegistryValueKind.DWord); + editor.SetValue("FontWeight", 400, RegistryValueKind.DWord); + return; + } + + var KCore_Thread = new Thread(() => + { + Console.Title = "KCore Editor Console"; + while (ConsoleHandler == IntPtr.Zero) + ConsoleHandler = FindWindow(null, Console.Title); + Terminal.Init(80, 25); + Terminal.UpdatesPerSecond = 0; + Terminal.KeySplit = 1; + Terminal.KeyWait = 1; + (ConsoleControl = new ConsoleControl()).Start(); + }); + KCore_Thread.Start(); + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(MainForm = new MainForm()); + } + } +} diff --git a/Editor/Properties/AssemblyInfo.cs b/Editor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cc7f6e9 --- /dev/null +++ b/Editor/Properties/AssemblyInfo.cs @@ -0,0 +1,94 @@ +using System.IO; +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using KCore.Extensions.InsteadSLThree; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанных со сборкой. +[assembly: AssemblyTitle(EditorVersion.Name)] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct(EditorVersion.Name)] +[assembly: AssemblyCopyright(EditorVersion.Copyright)] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// COM, следует установить атрибут ComVisible в TRUE для этого типа. +[assembly: ComVisible(false)] + +// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM +[assembly: Guid("7450c379-dd7c-410e-a122-a96ef8082f37")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Редакция +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion(EditorVersion.Version)] +[assembly: AssemblyFileVersion(EditorVersion.Version)] + +public static class EditorVersion +{ + public class Reflected + { + public int Major { get; private set; } + public int Minor { get; private set; } + public int Build { get; private set; } + public int Revision { get; private set; } + public DateTime LastUpdate { get; private set; } + + public string Version { get; private set; } + public string VersionWithoutRevision { get; private set; } + + public Reflected() + { + var slt_version = typeof(EditorVersion); + Major = int.Parse(slt_version.GetField("Major").GetValue(null).Cast()); + Minor = int.Parse(slt_version.GetField("Minor").GetValue(null).Cast()); + Build = int.Parse(slt_version.GetField("Build").GetValue(null).Cast()); + Revision = int.Parse(slt_version.GetField("Revision").GetValue(null).Cast()); + LastUpdate = new DateTime(slt_version.GetField("LastUpdate").GetValue(null).Cast()); + + Version = Major + "." + Minor + "." + Build + "." + Revision; + VersionWithoutRevision = Major + "." + Minor + "." + Build; + } + } + + public const string Major = "0"; //vh + public const string Minor = "1"; //vh + public const string Build = "0"; //vh + public const string Revision = "53"; //vh + public const long LastUpdate = 638396998313907149; //vh + + public const string Version = Major + "." + Minor + "." + Build + "." + Revision; + public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; + public const string VersionRevisionInBrackets = Major + "." + Minor + "." + Build + " (" + Revision + ")"; + public const string Name = "KCore Editor"; + public const string Author = "Alexandr Kotov"; + public const string Copyright = Author + " 2023"; + + internal static string[] ReadStrings(Stream stream) + { + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd().Split(new string[1] { Environment.NewLine }, StringSplitOptions.None); + } + } + + static EditorVersion() + { + var ass = Assembly.GetExecutingAssembly(); + + } +} diff --git a/Editor/Properties/Resources.Designer.cs b/Editor/Properties/Resources.Designer.cs new file mode 100644 index 0000000..2fb801d --- /dev/null +++ b/Editor/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программным средством. +// Версия среды выполнения: 4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если +// код создан повторно. +// +//------------------------------------------------------------------------------ + +namespace Editor.Properties +{ + + + /// + /// Класс ресурсов со строгим типом для поиска локализованных строк и пр. + /// + // Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder + // класс с помощью таких средств, как ResGen или Visual Studio. + // Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen + // с параметром /str или заново постройте свой VS-проект. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Возврат кэшированного экземпляра ResourceManager, используемого этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Editor.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Переопределяет свойство CurrentUICulture текущего потока для всех + /// подстановки ресурсов с помощью этого класса ресурсов со строгим типом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Editor/Properties/Resources.resx b/Editor/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Editor/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Editor/Properties/Settings.Designer.cs b/Editor/Properties/Settings.Designer.cs new file mode 100644 index 0000000..d651dc6 --- /dev/null +++ b/Editor/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Editor.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Editor/Properties/Settings.settings b/Editor/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Editor/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/KCore.nuspec b/KCore.nuspec index a395af5..a226c23 100644 --- a/KCore.nuspec +++ b/KCore.nuspec @@ -2,23 +2,20 @@ KCore - 0.1.0 + 0.2.0 Kotov false MIT A simple but powerful shell for creating applications in the Windows console ------- KCore 0.1.0 ------ [10.12.23] -The first version. Not everything from KTXCore has been adapted yet. -Main from KTXCore: - - Transition animations - - Graphics architecture -New: - - Widgets, new Forms, Requests instead Reactions +------ KCore 0.2.0 ------ [01.01.24] +Main: + - New DASHBOARD + - Storage for KCore applications + - Localizations (en, ru) + - Inifile -> Initial New widgets: - - Window, BoxLayout, ListBox - - WithVerticalScroll, VerticalScroll, Padding - - ScrollableText, TextWidget, TextRow + - Panel (Form is also Panel) $copyright$ windows console shell terminal widgets diff --git a/KCore.sln b/KCore.sln index 5c48f72..6f264e3 100644 --- a/KCore.sln +++ b/KCore.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KCore", "KCore\KCore.csproj EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Runner", "Runner\Runner.csproj", "{DE417F09-8B21-4D00-961E-54F352118A21}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Editor", "Editor\Editor.csproj", "{7450C379-DD7C-410E-A122-A96EF8082F37}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {DE417F09-8B21-4D00-961E-54F352118A21}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE417F09-8B21-4D00-961E-54F352118A21}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE417F09-8B21-4D00-961E-54F352118A21}.Release|Any CPU.Build.0 = Release|Any CPU + {7450C379-DD7C-410E-A122-A96EF8082F37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7450C379-DD7C-410E-A122-A96EF8082F37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7450C379-DD7C-410E-A122-A96EF8082F37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7450C379-DD7C-410E-A122-A96EF8082F37}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/KCore/CoreForms/Dashboard.cs b/KCore/CoreForms/Dashboard.cs index cf6498f..7a5ff77 100644 --- a/KCore/CoreForms/Dashboard.cs +++ b/KCore/CoreForms/Dashboard.cs @@ -1,9 +1,18 @@ -using KCore.Graphics; +using KCore.Extensions.InsteadSLThree; +using KCore.Extensions; +using KCore.Graphics; +using KCore.Graphics.Containers; +using KCore.Graphics.Core; +using KCore.Graphics.Widgets; +using KCore.Storage; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Security.Permissions; namespace KCore.CoreForms { @@ -12,75 +21,1078 @@ internal class Dashboard : Form public static KCoreVersion.Reflected Version = new KCoreVersion.Reflected(); public TriggerRedrawer Downline; - public Dashboard() + //Dashboard options: + //KCore version info (+ difference list) + //KCore settings + //KCore Form information + //KCore Palette + //SLThree console (if SLThree.dll available) + + public static class Settings { - Bind(Downline = new TriggerRedrawer(this, form => + public static readonly Type SettingsType = typeof(Settings); + public static Type EntryType = null; + + public const int Spacing = 40; + public abstract class Setting : Widget { - Terminal.Set(1, Terminal.FixedWindowHeight - 1); - ($"KCore {Version.Version} %=>DarkCyan%{Terminal.FixedWindowWidth}x{Terminal.FixedWindowHeight}%=>reset% " - + $"%=>Red%{Terminal.UpdatesPerSecond} UPS%=>reset%").PrintSuperText(); - })); + public Dashboard Reference; + public virtual bool HasTitle => false; + public override bool AllowedVisible => base.AllowedVisible; + public virtual bool HasValue => true; + public override int Height => HasTitle ? 3 : 1; + public override int Width => Container.Width; + public override void Resize() { } + public override (int, int) Clear(int left, int top) + { + Graph.FillRectangle(Theme.Back, left, top, Width, Height); + return (left, top); + } + public Setting(Dashboard dashboard) : base(0, 0, null, null, true, false) + { + Reference = dashboard; + } + + public virtual void OnEntered() { } + public virtual void OnLeaving() { } + + public IContainer GetSettingKeyContainer(int left, int top) + { + return new StaticContainer(left + 2, top, Spacing - 2, 1); + } + + public IContainer GetSettingValueContainer(int left, int top) + { + return new StaticContainer(left + Spacing + 2, top, Width - Spacing - 2, 1); + } + + public IContainer GetContainer(int left, int top) + { + return new StaticContainer(left + 2, top, Width - 2, 1); + } + + public override (int, int) Draw(int left, int top) + { + if (HasTitle) + { + Terminal.Set(left, ++top); + Terminal.Write(Title.PadCenter(Width).Replace(' ', '-').Replace('_', ' ')); + top += 1; + } + + if (HasValue) + { + GetSettingKey().PrintSuperText(GetSettingKeyContainer(left, top), null, TextAlignment.Left); + Terminal.Set(left + Spacing, top); + Terminal.Write(": "); + var value_container = GetSettingValueContainer(left, top); + Graph.FillRectangle(Theme.Back, value_container); + GetSettingValue().PrintSuperText(value_container, null, TextAlignment.Left); + } + else + { + GetSettingKey().PrintSuperText(GetContainer(left, top), null, TextAlignment.Left); + } + + return (left, top); + } + + public override bool SelectNeedsRedraw => true; + + public virtual string Title => ""; + public abstract string GetSettingKey(); + public abstract string GetSettingValue(); + public bool IsActive => Reference.FieldSettingsPanel.ActiveSubwidget == this; + } + + public abstract class OnlyKeySetting : Setting + { + public override bool HasValue => false; + public override string GetSettingValue() => ""; + public OnlyKeySetting(Dashboard dashboard) : base(dashboard) + { + } + } + + public class Language : Setting, IControlable + { + public Language(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + public override IList GetBinds(Form form) + { + return new Request[] { + EnterTrigger = new Trigger(form, panel => + { + Localization.Next(); + (panel as Form).Clear(); + KCoreStorage.SaveGlobalConfig(); + }) + }; + } + public override bool HasTitle => true; + public override string Title => Localization.Current["DASH_MAIN"]; + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_Language"]; + + public override string GetSettingValue() + { + var str = Localization.Current.LocalName; + return IsActive ? $"%=>Magenta%{str}%=>reset%" : str; + } + } + + public class ConsoleSize : Setting, IControlable + { + public ConsoleSize(Dashboard dashboard) : base(dashboard) { } + + public Trigger UpTrigger; + public Trigger DownTrigger; + public Trigger LeftTrigger; + public Trigger RightTrigger; + public override bool HasTitle => true; + public override string Title => Localization.Current["DASH_GRAPHICS"]; + public bool HeightResizing; + public bool SavedWSEM; + + public override void OnEntered() + { + SavedWSEM = Terminal.WindowSizeExternalManage; + Terminal.WindowSizeExternalManage = false; + } + + public override void OnLeaving() + { + Terminal.WindowSizeExternalManage = SavedWSEM; + } + + public override IList GetBinds(Form form) + { + return new Request[] { + UpTrigger = new Trigger(form, panel => + { + if (HeightResizing) + Terminal.FixedWindowHeight += 1; + else Terminal.FixedWindowWidth += 1; + KCoreStorage.SaveLocalConfig(); + }), + DownTrigger = new Trigger(form, panel => + { + if (HeightResizing) + Terminal.FixedWindowHeight -= 1; + else Terminal.FixedWindowWidth -= 1; + KCoreStorage.SaveLocalConfig(); + }), + LeftTrigger = new Trigger(form, panel => + { + HeightResizing = false; + Redraw(); + }), + RightTrigger = new Trigger(form, panel => + { + HeightResizing = true; + Redraw(); + }), + }; + } + + public void OnKeyDown(byte key) + { + if (key == Key.A || key == Key.LeftArrow) + LeftTrigger.Pull(); + if (key == Key.D || key == Key.RightArrow) + RightTrigger.Pull(); + if (key == Key.W || key == Key.UpArrow) + UpTrigger.Pull(); + if (key == Key.S || key == Key.DownArrow) + DownTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_ConsoleSize"]; + + public override string GetSettingValue() + { + var width = Terminal.FixedWindowWidth.ToString(); + var height = Terminal.FixedWindowHeight.ToString(); + if (Reference.FieldSettingsPanel.ActiveSubwidget == this) + { + if (HeightResizing) height = $"%=>Magenta%{height}%=>reset%"; + else width = $"%=>Magenta%{width}%=>reset%"; + } + return $"{width}x{height}"; + } + } + + public class MakeMaximal : OnlyKeySetting, IControlable + { + public MakeMaximal(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + public bool HeightResizing; + public bool SavedWSEM; + + public override IList GetBinds(Form form) + { + return new Request[] { + EnterTrigger = new Trigger(form, panel => + { + (Terminal.FixedWindowWidth, Terminal.FixedWindowHeight) = (Console.LargestWindowWidth, Console.LargestWindowHeight); + KCoreStorage.SaveLocalConfig(); + (panel as Dashboard).Clear(); + }), + }; + } + + public override void OnEntered() + { + SavedWSEM = Terminal.WindowSizeExternalManage; + Terminal.WindowSizeExternalManage = false; + } + + public override void OnLeaving() + { + Terminal.WindowSizeExternalManage = SavedWSEM; + } + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => IsActive ? $"%=>Magenta%{Localization.Current["DASH_MakeMaximal"]}%=>reset%": Localization.Current["DASH_MakeMaximal"]; + } + + public class MakeMinimal : OnlyKeySetting, IControlable + { + public MakeMinimal(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + public bool HeightResizing; + public bool SavedWSEM; + + public override IList GetBinds(Form form) + { + return new Request[] { + EnterTrigger = new Trigger(form, panel => + { + (Terminal.FixedWindowWidth, Terminal.FixedWindowHeight) = (Terminal.MinimalWindowWidth, Terminal.MinimalWindowHeight); + KCoreStorage.SaveLocalConfig(); + (panel as Dashboard).Clear(); + }), + }; + } + public override void OnEntered() + { + SavedWSEM = Terminal.WindowSizeExternalManage; + Terminal.WindowSizeExternalManage = false; + } + + public override void OnLeaving() + { + Terminal.WindowSizeExternalManage = SavedWSEM; + } + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + + public override string GetSettingKey() => IsActive ? $"%=>Magenta%{Localization.Current["DASH_MakeMinimal"]}%=>reset%" : Localization.Current["DASH_MakeMinimal"]; + } + + public class ExternalSize : Setting, IControlable + { + public ExternalSize(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + + public override IList GetBinds(Form form) + { + return new Request[1] { EnterTrigger = new Trigger(form, x => + { + Terminal.WindowSizeExternalManage = !Terminal.WindowSizeExternalManage; + KCoreStorage.SaveLocalConfig(); + Redraw(); + })}; + } + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_ExternalResizing"]; + + public bool GetWSEM() + { + if (Reference.FieldSettingsPanel.ActiveSubwidget?.GetType() == typeof(ConsoleSize)) + return (Reference.FieldSettingsPanel.ActiveSubwidget as ConsoleSize).SavedWSEM; + else return Terminal.WindowSizeExternalManage; + } + + public override string GetSettingValue() + { + var str = GetWSEM() ? Localization.Current["DASH_Enabled"] : Localization.Current["DASH_Disabled"]; + return IsActive ? $"%=>Magenta%{str}%=>reset%" : str; + } + } + + public class UpdatesPerSec : Setting, IControlable + { + public Trigger LeftTrigger; + public Trigger RightTrigger; + public static string GetText() + { + if (Terminal.UpdatesPerSecond == 0) + return Localization.Current["DASH_Unlimited"]; + return Terminal.UpdatesPerSecond.ToString(); + } + + public static int[] Allowed = new int[] { 12, 24, 44, 70, 0 }; + + public UpdatesPerSec(Dashboard dashboard) : base(dashboard) { } + + public override IList GetBinds(Form form) + { + return new Request[] { + LeftTrigger = new Trigger(form, panel => + { + var ind = Array.IndexOf(Allowed, Terminal.UpdatesPerSecond); + if (ind == -1) ind = 0; + ind--; + if (ind < 0) ind = 0; + Terminal.UpdatesPerSecond = Allowed[ind]; + KCoreStorage.SaveLocalConfig(); + Redraw(); + }), + RightTrigger = new Trigger(form, panel => + { + var ind = Array.IndexOf(Allowed, Terminal.UpdatesPerSecond); + if (ind == -1) ind = Allowed.Length - 1; + ind++; + if (ind >= Allowed.Length) ind = Allowed.Length - 1; + Terminal.UpdatesPerSecond = Allowed[ind]; + KCoreStorage.SaveLocalConfig(); + Redraw(); + }), + }; + } + + public void OnKeyDown(byte key) + { + if (key == Key.A || key == Key.LeftArrow) + LeftTrigger.Pull(); + if (key == Key.D || key == Key.RightArrow) + RightTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_UpdatesPerSec"]; + public override string GetSettingValue() + { + var str = GetText().ToString(); + return IsActive ? $"%=>Magenta%{str}%=>reset%" : str; + } + } + + public class TransitionAnimations : Setting, IControlable + { + public TransitionAnimations(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + + public override IList GetBinds(Form form) + { + return new Request[1] { EnterTrigger = new Trigger(form, x => + { + GraphicsExtensions.AllowTransitionAnimations = !GraphicsExtensions.AllowTransitionAnimations; + KCoreStorage.SaveLocalConfig(); + Redraw(); + })}; + } + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_TransitionAnimations"]; + public override string GetSettingValue() + { + var str = GraphicsExtensions.AllowTransitionAnimations ? Localization.Current["DASH_Enabled"] : Localization.Current["DASH_Disabled"]; + return IsActive ? $"%=>Magenta%{str}%=>reset%" : str; + } + } + + public class TransitionAnimationSpeed : Setting, IControlable + { + public Trigger LeftTrigger; + public Trigger RightTrigger; + + public static int[] Allowed = new int[] { 1, 2, 3, 4, 5, 7, 10, 15, 20, 25, 30, 35, 40 }; + + public TransitionAnimationSpeed(Dashboard dashboard) : base(dashboard) { } + + public override IList GetBinds(Form form) + { + return new Request[] { + LeftTrigger = new Trigger(form, panel => + { + var ind = Array.IndexOf(Allowed, GraphicsExtensions.TransitionAnimationsSpeed); + if (ind == -1) ind = 0; + ind--; + if (ind < 0) ind = 0; + GraphicsExtensions.TransitionAnimationsSpeed = Allowed[ind]; + KCoreStorage.SaveLocalConfig(); + Redraw(); + }), + RightTrigger = new Trigger(form, panel => + { + var ind = Array.IndexOf(Allowed, GraphicsExtensions.TransitionAnimationsSpeed); + if (ind == -1) ind = Allowed.Length - 1; + ind++; + if (ind >= Allowed.Length) ind = Allowed.Length - 1; + GraphicsExtensions.TransitionAnimationsSpeed = Allowed[ind]; + KCoreStorage.SaveLocalConfig(); + Redraw(); + }), + }; + } + + public void OnKeyDown(byte key) + { + if (key == Key.A || key == Key.LeftArrow) + LeftTrigger.Pull(); + if (key == Key.D || key == Key.RightArrow) + RightTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_TransitionAnimationSpeed"]; + public override string GetSettingValue() + { + return IsActive ? $"%=>Magenta%{GraphicsExtensions.TransitionAnimationsSpeed}%=>reset%" : GraphicsExtensions.TransitionAnimationsSpeed.ToString(); + } + } + + public class CurrentApplication : Setting, IControlable + { + public CurrentApplication(Dashboard dashboard) : base(dashboard) { } + + public override bool HasTitle => true; + public override string Title => Localization.Current["DASH_ADVANCED"]; + + public override IList GetBinds(Form form) + { + return Array.Empty(); + } + + public void OnKeyDown(byte key) + { + //if (key == Key.E || key == Key.Enter) + // EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_CurrentApplication"]; + public override string GetSettingValue() => KCoreStorage.Portable ? Localization.Current["DASH_Portable"] : Localization.Current["DASH_Common"]; + } + + public class ShowUPS : Setting, IControlable + { + public ShowUPS(Dashboard dashboard) : base(dashboard) { } + + public Trigger EnterTrigger; + + public override IList GetBinds(Form form) + { + return new Request[1] { EnterTrigger = new Trigger(form, panel => + { + Form.ShowUPS = !Form.ShowUPS; + (panel as Form).Clear(); + })}; + } + + public void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + } + + public void OnKeyUp(byte key) { } + + public override string GetSettingKey() => Localization.Current["DASH_ShowUPS"]; + public override string GetSettingValue() + { + var str = Form.ShowUPS ? Localization.Current["DASH_Enabled"] : Localization.Current["DASH_Disabled"]; + return IsActive ? $"%=>Magenta%{str}%=>reset%": str; + } + } } - protected override bool IsRecursiveForm() => true; + public abstract class DashboardPanel : Panel + { + public DashboardPanel(Form form) : base(form) { } - protected override void OnAllRedraw() + public abstract string PanelName { get; } + public abstract bool LockChanger { get; } + } + + public class SettingsPanel : DashboardPanel, IControlable + { + public override string PanelName => Localization.Current["DASH_PN_Settings"]; + public override bool LockChanger => ActiveSubwidget != null; + public ListBox SettingsList; + public Trigger EnterAction; + public Trigger BackAction; + public IControlable ActiveSubwidget; + + public SettingsPanel(Form form) : base(form) + { + SettingsList = new ListBox(); + SettingsList.SelectingPadding = (-1, 0); + SettingsList.SelectingLocation = ListBox.Location.Left; + SettingsList.SelectingRelativeChildLocation = ListBox.RelativeLocation.Down; + SettingsList.Container = new DynamicContainer() + { + GetLeft = () => 1, + GetTop = () => 3, + GetHeight = () => Terminal.FixedWindowHeight - 5, + GetWidth = () => Terminal.FixedWindowWidth - 2, + }; + SettingsList.Childs = typeof(Settings).GetNestedTypes().Where(x => x.BaseType == typeof(Settings.OnlyKeySetting) || x.BaseType == typeof(Settings.Setting) && !(x == typeof(Settings.OnlyKeySetting))) + .Select(x => new ListBox.ListItem(Activator.CreateInstance(x, new object[1] { form as Dashboard }) as Widget)).ToList(); + + OnResizing += panel => SettingsList.Resize(); + + Bind(SettingsList); + foreach (var x in SettingsList.Childs) + { + Bind(x.Child); + foreach (var req in x.Child.GetBinds(form)) + Bind(req); + } + Bind(EnterAction = new Trigger(this, panel => (panel as SettingsPanel).Enter())); + Bind(BackAction = new Trigger(this, panel => (panel as SettingsPanel).Back())); + + Optimize(); + } + + public void Enter() + { + ActiveSubwidget = SettingsList.Childs[SettingsList.Position].Child as IControlable; + var setting = ActiveSubwidget as Settings.Setting; + setting.OnEntered(); + setting.Redraw(); + } + + public void Back() + { + ActiveSubwidget = null; + var setting = SettingsList.Childs[SettingsList.Position].Child as Settings.Setting; + setting.OnLeaving(); + setting.Redraw(); + } + + public void OnKeyDown(byte key) + { + if (ActiveSubwidget == null) + { + if (key == Key.E || key == Key.Enter) + EnterAction.Pull(); + else SettingsList.OnKeyDown(key); + } + else + { + if (key == Key.Tab || key == Key.Backspace) + BackAction.Pull(); + else ActiveSubwidget.OnKeyDown(key); + } + + } + + public void OnKeyUp(byte key) + { + if (ActiveSubwidget == null) + SettingsList.OnKeyUp(key); + else ActiveSubwidget.OnKeyUp(key); + } + } + + public class FormPanel : DashboardPanel, IControlable { + public override string PanelName => Localization.Current["DASH_PN_FormInfo"]; + public override bool LockChanger => false; + public TriggerRedrawer OldFormInfoRedrawer; - var extras = new string[] + public FormPanel(Form form) : base(form) { - "EXTRA KEYS", "F2 - External resize", "F3/F4 - Height -/+", "F5/F6 - Width -/+", - "F7 - Show UPS", "F8 - UPS unlim", "F9 - Pause KCore", "F10 - All redraw" + Bind(OldFormInfoRedrawer = new TriggerRedrawer(form, panel => + { + var dashboard = (panel as Form); + var Reference = dashboard.Reference; + + Terminal.Set(1, 4); + $"{Localization.Current["DASH_F_Current"]}: %=>Red%{Reference?.GetType().FullName ?? "null"}%=>reset%".PrintSuperText(); + if (Reference != null) + { + var req = Reference.Requests; + Terminal.Set(4, 5); + $"{Localization.Current["DASH_F_StartedFrom"]}: %=>Red%{Reference.Reference?.GetType().FullName ?? "null"}%=>reset%".PrintSuperText(); + Terminal.Set(4, 6); + $"{Localization.Current["DASH_F_FormTimer"]}: %=>DarkGreen%{Reference.FormTimer.TotalSeconds:0.##}%=>reset% {Localization.Current["DASH_F_sec"]}".PadRight(50).PrintSuperText(); + Terminal.Set(4, 7); + $"{Localization.Current["DASH_F_Delay"]}: %=>DarkGreen%{Reference.RealUPS.TotalMilliseconds:0.##}%=>reset% {Localization.Current["DASH_F_msec"]}".PadRight(50).PrintSuperText(); + Terminal.Set(4, 8); + $"{Localization.Current["DASH_F_Total"]}: %=>DarkGreen%{req.Count(x => x.AllRedraw)}%=>reset%/%=>DarkGreen%{req.Length}%=>reset%".PrintSuperText(); + Terminal.Set(4, 9); + var childs = Reference.Root.GetChilds(); + $"{Localization.Current["DASH_F_RootWidgets"]}: %=>DarkGreen%{childs.Length}%=>reset%".PrintSuperText(); + var max = Math.Min(Terminal.FixedWindowHeight - 12, childs.Length); + for (var i = 0; i < max; i++) + { + Terminal.Set(7, 10 + i); + var type = childs[i].GetType(); + var assembly = type.Assembly.GetName().Name; + var name = type.Name; + $"%=>Blue%[{assembly}]%=>reset% {name}".PrintSuperText(); + } + } + })); + Optimize(); + } + + public void OnKeyDown(byte key) + { + + } + + public void OnKeyUp(byte key) + { + + } + } + + public class PalettePanel : DashboardPanel, IControlable + { + public override string PanelName => Localization.Current["DASH_PN_Palette"]; + public override bool LockChanger => false; + public TriggerRedrawer PaletteRedrawer; + public string chars = Chars.MixingMultipliers.Keys.ToArray().JoinIntoString(""); + + public PalettePanel(Form form) : base(form) + { + + Bind(PaletteRedrawer = new TriggerRedrawer(form, panel => + { + Terminal.Set(1, 4); + Terminal.Write(Localization.Current["DASH_PaletteInfo"]); + Terminal.ResetColor(); + var j = 0; + foreach (var x in chars.Batch(Terminal.FixedWindowWidth / 2 + Terminal.FixedWindowWidth / 3)) + { + Terminal.Set(2, j + 6); + Terminal.Write(x.JoinIntoString("")); + j += 1; + } + Terminal.ResetColor(); + })); + Optimize(); + } + + public void OnKeyDown(byte key) + { + + } + + public void OnKeyUp(byte key) + { + + } + } + + public class VersionPanel : DashboardPanel, IControlable + { + private const string DeveloperNotSpecify = "#DNS#"; + #region KCore Version API + + public static Func GetEntryVersion = () => + { + var assembly = Assembly.GetEntryAssembly(); + var ret = new KCoreVersionInfo(); + var name = assembly.GetName(); + ret.Name = name.Name; + ret.Copyright = assembly.GetCustomAttribute().Copyright; + ret.Version = name.Version.ToString(); + ret.Differences = new KeyValuePair[1] { + new KeyValuePair(ret.Version.ToString(), DeveloperNotSpecify) + }; + return ret; + }; + public interface IKCoreVersionInfo + { + string Copyright { get; set; } + KeyValuePair[] Differences { get; set; } + string Name { get; set; } + string Version { get; set; } + } + + #region non-public + internal class KCoreVersionInfo : IKCoreVersionInfo + { + public string Name { get; set; } + public string Copyright { get; set; } + public string Version { get; set; } + public KeyValuePair[] Differences { get; set; } + } + + private static KeyValuePair[] kcore_diffs; + + static VersionPanel() + { + var kcore_ass = Assembly.GetExecutingAssembly(); + kcore_diffs = kcore_ass.GetManifestResourceNames().Where(x => x.StartsWith("KCore.docs.versions.")) + .Select(x => new KeyValuePair(x.Replace("KCore.docs.versions.", ""), kcore_ass.GetManifestResourceStream(x).ReadString())).ToArray(); + } + + internal static Func GetKCoreVersion = () => + { + return new KCoreVersionInfo() + { + Name = KCoreVersion.Name, + Copyright = KCoreVersion.Copyright, + Version = Version.Version, + Differences = kcore_diffs, + }; }; - var left = Terminal.FixedWindowWidth - extras.Select(x => x.Length).Max() - 1; - for (var i = 0; i < extras.Length; i++) + #endregion + #endregion + + public IKCoreVersionInfo KCoreVersionInformation; + public IKCoreVersionInfo EntryVersionInformation; + + public string[] VersionContent; + public ListBox VersionList; + public ScrollableText VersionText; + public Window VersionShow; + public TriggerRedrawer MainInfoRedrawer; + private Localization last_localization; + + public VersionPanel(Form form) : base(form) { - Terminal.Set(left, 1 + i); - Terminal.Write(extras[i]); + KCoreVersionInformation = GetKCoreVersion(); + EntryVersionInformation = GetEntryVersion(); + + VersionList = new ListBox(); + + var initial_diffs = EntryVersionInformation.Differences.OrderByDescending(x => x.Key) + .Select(x => (x.Value, $"{EntryVersionInformation.Name} {x.Key}")) + .Concat(KCoreVersionInformation.Differences.OrderByDescending(x => x.Key) + .Select(x => (x.Value, $"{KCoreVersionInformation.Name} {x.Key}"))); + + + VersionContent = initial_diffs.Select(x => x.Item1).ToArray(); + VersionList.Childs = + initial_diffs.Select(x => x.Item2) + .Select(x => new ListBox.ListItem(new TextWidget(x, alignment: Alignment.LeftWidth | Alignment.UpHeight, fillHeight: false))) + .ToList(); + VersionList.SelectingPadding = (1, 1); + + var max = initial_diffs.Select(x => x.Item2).MaxBy(x => x).Length; + VersionList.Container = new DynamicContainer() + { + GetLeft = () => 1, + GetTop = () => 4, + GetWidth = () => max + 4, + GetHeight = () => 4, + }; + var scroll = new VerticalScroll(VersionList, container: new DynamicContainer() + { + GetLeft = () => max + 5, + GetTop = () => 4, + GetWidth = () => 1, + GetHeight = () => 4, + }, pixel: ' ', scrollPixel: '▐'); + VersionList.Scroll = scroll; + scroll.Resize(); + Bind(scroll); + + VersionList.Resize(); + VersionList.OnChanged += list_box => + { + VersionText.Text = VersionContent[VersionList.Position]; + VersionShow.Resize(); + VersionText.Redraw(); + }; + Bind(VersionList); + + VersionShow = new Window( + VersionText = new ScrollableText(VersionContent[0], textAlignment: TextAlignment.Left) + ); + VersionShow.HasBorder = false; + VersionShow.Padding = (0, 0, 0, 0); + VersionText.Autoscroll = true; + Bind(VersionText); + + VersionShow.Container = new DynamicContainer() + { + GetLeft = () => 1, + GetTop = () => 9, + GetWidth = () => Terminal.FixedWindowWidth - 2, + GetHeight = () => Terminal.FixedWindowHeight - 10, + }; + VersionShow.Resize(); + Bind(VersionShow); + + Bind(MainInfoRedrawer = new TriggerRedrawer(form, __ => + { + var cont = new StaticContainer(max + 8, 4, Terminal.FixedWindowWidth - max - 8, 2); + var cont2 = new StaticContainer(max + 8, 6, Terminal.FixedWindowWidth - max - 8, 2); + + string.Format(Localization.Current["DASH_EntryBy"], EntryVersionInformation.Name, EntryVersionInformation.Version, EntryVersionInformation.Copyright, KCoreStorage.EntryLINK).PrintSuperText(cont); + + string.Format(Localization.Current["DASH_KCoreBy"], KCoreVersionInformation.Name, KCoreVersionInformation.Version, KCoreVersionInformation.Copyright, KCoreStorage.KCoreLINK).PrintSuperText(cont2); + })); + + Bind(new DelegateRequest(form, frm => VersionText.Text.StartsWith(DeveloperNotSpecify) || last_localization != Localization.Current, frm => + { + if (Localization.Current != last_localization && VersionContent[VersionList.Position].StartsWith(DeveloperNotSpecify)) + { + VersionText.Text = VersionContent[VersionList.Position].Replace(DeveloperNotSpecify, string.Format(Localization.Current["DASH_VersionUndefined"], EntryVersionInformation.Name)); + } + else VersionText.Text = VersionText.Text.Replace(DeveloperNotSpecify, string.Format(Localization.Current["DASH_VersionUndefined"], EntryVersionInformation.Name)); + last_localization = Localization.Current; + VersionText.Resize(); + VersionText.Redraw(); + })); + + Optimize(); } - Terminal.Set(Terminal.FixedWindowWidth - 11, Terminal.FixedWindowHeight - 1); - Terminal.Write("Close: F12"); + public override string PanelName => Localization.Current["DASH_PN_Version"]; - Terminal.Set(1, 1); - $"Current: %=>Red%{Reference?.GetType().FullName ?? "null"}%=>reset%".PrintSuperText(); - if (Reference != null) + public override bool LockChanger => false; + + public void OnKeyDown(byte key) + { + VersionList.OnKeyDown(key); + } + + public void OnKeyUp(byte key) + { + + } + } + + public class PanelChanger : Widget, IControlable + { + public Dashboard Reference; + public Trigger LeftTrigger; + public Trigger RightTrigger; + + public PanelChanger(Dashboard form) + { + Reference = form; + Container = new DynamicContainer() + { + GetLeft = () => 0, + GetTop = () => 1, + GetWidth = () => Terminal.FixedWindowWidth, + GetHeight = () => 2 + }; + } + + public override IList GetBinds(Form form) + { + return new Request[] + { + LeftTrigger = new Trigger(form, x => Prev()), + RightTrigger = new Trigger(form, x => Next()), + }; + } + + + public void Prev() + { + var ind = Array.FindIndex(Reference.Panels, x => Reference.current_panel == x); + var xind = ind; + ind--; + if (ind < 0) ind = 0; + if (xind != ind) + { + Reference.CurrentPanel = Reference.Panels[ind] as IControlable; + Reference.Clear(); + } + } + public void Next() { - var req = Reference.Requests; - Terminal.Set(4, 2); - $"Started from: %=>Red%{Reference.Reference?.GetType().FullName ?? "null"}%=>reset%".PrintSuperText(); - Terminal.Set(4, 3); - $"FormTimer: %=>DarkGreen%{Reference.FormTimer.TotalSeconds:0.##}%=>reset% sec".PadRight(50).PrintSuperText(); - Terminal.Set(4, 4); - $"Delay: %=>DarkGreen%{Reference.RealUPS.TotalMilliseconds:0.##}%=>reset% ms".PadRight(50).PrintSuperText(); - Terminal.Set(4, 5); - $"Total redrawers/requests: %=>DarkGreen%{req.Count(x => x.AllRedraw)}%=>reset%/%=>DarkGreen%{req.Length}%=>reset%".PrintSuperText(); - Terminal.Set(4, 6); - $"Root widgets: %=>DarkGreen%{Reference.Root.Childs.Count}%=>reset%".PrintSuperText(); - var max = Math.Min(Terminal.FixedWindowHeight - 8, Reference.Root.Childs.Count); - for (var i = 0; i < max; i++) + var ind = Array.FindIndex(Reference.Panels, x => Reference.current_panel == x); + var xind = ind; + ind++; + if (ind >= Reference.Panels.Length) ind = Reference.Panels.Length - 1; + if (xind != ind) { - Terminal.Set(7, 7 + i); - var type = Reference.Root.Childs[i].GetType(); - var assembly = type.Assembly.GetName().Name; - var name = type.Name; - $"%=>Blue%[{assembly}]%=>reset% {name}".PrintSuperText(); + Reference.CurrentPanel = Reference.Panels[ind] as IControlable; + Reference.Clear(); } } + + public override IContainer Container { get => TerminalContainer.This; set { } } + public override int Width => Terminal.FixedWindowWidth; + public override int Height => 1; + public override void Resize() { } + public override bool AlwaysClear => true; + + public override (int, int) Draw(int left, int top) + { + var indent = 0; + Terminal.Set(0, 2); + Terminal.Write(Graph.Chars('─', Terminal.FixedWindowWidth)); + for (var i = 0; i < Reference.Panels.Length; i++) + { + var str = $"{Reference.Panels[i].PanelName}"; + if (Reference.CurrentPanel == Reference.Panels[i]) + { + Terminal.Set(1 + indent, 2); + Console.Write('┘' + Graph.Chars(' ', str.Length + 2) + '└'); + str = $"│ {str} │"; + } + else str = $" {str} "; + Terminal.Set(1 + indent, 1); + indent += str.Length + 2; + str.PrintSuperText(); + } + return (left, top); + } + public override (int, int) Clear(int left, int top) + { + Graph.FillRectangle(Theme.Back, this); + return (left, top); + } + + public void OnKeyDown(byte key) + { + Reference.CurrentPanel.OnKeyDown(key); + if ((Reference.CurrentPanel as DashboardPanel).LockChanger) return; + if (key == Key.A || key == Key.LeftArrow) + LeftTrigger.Pull(); + else if (key == Key.D || key == Key.RightArrow) + RightTrigger.Pull(); + } + public void OnKeyUp(byte key) + { + Reference.CurrentPanel.OnKeyUp(key); + } + } + + public PanelChanger Changer; + + public DashboardPanel[] Panels; + + public SettingsPanel FieldSettingsPanel; + public FormPanel FieldFormPanel; + public VersionPanel FieldVersionPanel; + public PalettePanel FieldPalettePanel; + + internal IControlable current_panel; + public IControlable CurrentPanel { get => current_panel; set + { + if (current_panel != null) + { + var panel1 = (current_panel as Panel); + panel1.Visible = false; + panel1.Enabled = false; + } + current_panel = value; + var panel2 = (current_panel as Panel); + panel2.Visible = true; + panel2.Enabled = true; + } } + + public Dashboard() + { + Bind(Downline = new TriggerRedrawer(this, form => + { + Terminal.Set(1, Terminal.FixedWindowHeight - 1); + ($"KCore {Version.Version}").PrintSuperText(); + })); + + FieldSettingsPanel = new SettingsPanel(this); + FieldFormPanel = new FormPanel(this); + FieldVersionPanel = new VersionPanel(this); + FieldPalettePanel = new PalettePanel(this); + + Panels = new DashboardPanel[] { FieldSettingsPanel, FieldFormPanel, FieldVersionPanel, FieldPalettePanel }; + foreach (var x in Panels) + { + Bind(x); + if (x == FieldSettingsPanel) continue; + x.Visible = false; + x.Enabled = false; + } + Bind(Changer = new PanelChanger(this)); + ActiveWidget = Changer; + } + + protected override void OnOpening() + { + CurrentPanel = FieldSettingsPanel; + Clear(); + } + + protected override void OnResize() + { + FieldSettingsPanel.Resize(); + } + + protected override bool IsRecursiveForm() => true; + + protected override void OnAllRedraw() + { + var str = Localization.Current["KCore_DASH_Close"]; + Terminal.Set(Terminal.FixedWindowWidth - 1 - str.Length, Terminal.FixedWindowHeight - 1); + Terminal.Write(str); } protected override void OnKeyDown(byte key) { + base.OnKeyDown(key); if (key == Key.F12) Close(); if (key == Key.OemPlus && Terminal.UpdatesPerSecond > 0) { Terminal.UpdatesPerSecond += 10; - Downline.Do(); + Downline.Pull(); } if (key == Key.OemMinus && Terminal.UpdatesPerSecond > 10) { Terminal.UpdatesPerSecond -= 10; - Downline.Do(); + Downline.Pull(); } } } diff --git a/KCore/CoreForms/ExceptionViewer.cs b/KCore/CoreForms/ExceptionViewer.cs index 0408f6d..6e3605a 100644 --- a/KCore/CoreForms/ExceptionViewer.cs +++ b/KCore/CoreForms/ExceptionViewer.cs @@ -152,10 +152,10 @@ private void ChangeStyle() private Trigger ExitRequest, RestartRequest, ChangeStyleRequest; protected override void OnKeyDown(byte key) { - if (key == Key.F5) ChangeStyleRequest.Do(); - else if (key == Key.Escape) ExitRequest.Do(); - else if (key == Key.Enter || key == Key.E || key == Key.Spacebar) RestartRequest.Do(); - else if (key != Key.Escape && key > 2) RestartRequest.Do(); + if (key == Key.F5) ChangeStyleRequest.Pull(); + else if (key == Key.Escape) ExitRequest.Pull(); + else if (key == Key.Enter || key == Key.E || key == Key.Spacebar) RestartRequest.Pull(); + else if (key != Key.Escape && key > 2) RestartRequest.Pull(); } } } diff --git a/KCore/CoreForms/ResizeViewer.cs b/KCore/CoreForms/ResizeViewer.cs index 5c25cd0..3807174 100644 --- a/KCore/CoreForms/ResizeViewer.cs +++ b/KCore/CoreForms/ResizeViewer.cs @@ -1,5 +1,6 @@ using KCore.Extensions; using KCore.Graphics; +using KCore.Storage; using System; using System.Collections.Generic; using System.Linq; @@ -12,14 +13,15 @@ public class ResizeViewer : Form { public static TimeSpan ResizePause = new TimeSpan(1 * TimeSpan.TicksPerSecond); public static bool ResizeStarted; - public static string YouAreResizingTheConsoleWindow = "You are resizing the console window"; - public static string GoingBackVia = "Going back via {0:0.0} secs"; + private static string YouAreResizingTheConsoleWindow => Localization.Current["KCore_Resizing1"]; + private static string GoingBackVia => Localization.Current["KCore_Resizing2"]; public ResizeViewer() { + AllowedDashboard = false; LastResize = FormTimer; - Bind(new DelegateRequest(this, form => (form.FormTimer - LastResize) > ResizePause, form => Close())); - Bind(new Redrawer(this, form => (form.FormTimer - LastSecsRedrawed).TotalMilliseconds > 5, form => RedrawSecs())); + Bind(new DelegateRequest(this, form => ((form as Form).FormTimer - LastResize) > ResizePause, form => Close())); + Bind(new Redrawer(this, form => ((form as Form).FormTimer - LastSecsRedrawed).TotalMilliseconds > 5, form => RedrawSecs())); } public TimeSpan LastResize; @@ -28,11 +30,11 @@ public ResizeViewer() public void RedrawSecs() { LastSecsRedrawed = FormTimer; - Terminal.Set(0, Terminal.FixedWindowHeight / 2); + Terminal.Set(10, Terminal.FixedWindowHeight / 2); Terminal.Write(string.Format( GoingBackVia, (LastResize - FormTimer + ResizePause) - .TotalSeconds.Round(1)).PadCenter(Terminal.FixedWindowWidth)); + .TotalSeconds.Round(1)).PadCenter(Terminal.FixedWindowWidth - 20)); } protected override void OnOpening() @@ -52,10 +54,17 @@ protected override void OnResize() protected override void OnAllRedraw() { - Terminal.Set(0, Terminal.FixedWindowHeight / 2 - 2); - Terminal.Write($"{Terminal.FixedWindowWidth}x{Terminal.FixedWindowHeight}".PadCenter(Terminal.FixedWindowWidth)); - Terminal.Set(0, Terminal.FixedWindowHeight / 2 - 1); - Terminal.Write(YouAreResizingTheConsoleWindow.PadCenter(Terminal.FixedWindowWidth)); + Terminal.Set(10, Terminal.FixedWindowHeight / 2 - 2); + Terminal.Write($"{Terminal.FixedWindowWidth}x{Terminal.FixedWindowHeight}".PadCenter(Terminal.FixedWindowWidth - 20)); + Terminal.Set(10, Terminal.FixedWindowHeight / 2 - 1); + Terminal.Write(YouAreResizingTheConsoleWindow.PadCenter(Terminal.FixedWindowWidth - 20)); + + Terminal.Back = Theme.Fore; + Graph.Row((Terminal.FixedWindowWidth - 20) / 2, 0, 20); + Graph.Row((Terminal.FixedWindowWidth - 20) / 2, Terminal.FixedWindowHeight - 1, 20); + Graph.Column(0, (Terminal.FixedWindowHeight - 6) / 2, 6); + Graph.Column(Terminal.FixedWindowWidth - 1, (Terminal.FixedWindowHeight - 6) / 2, 6); + Terminal.ResetColor(); } } } diff --git a/KCore/Extensions/InsteadSLThree/SLThreeExtensions.cs b/KCore/Extensions/InsteadSLThree/SLThreeExtensions.cs index 7e37bda..9faeace 100644 --- a/KCore/Extensions/InsteadSLThree/SLThreeExtensions.cs +++ b/KCore/Extensions/InsteadSLThree/SLThreeExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Text; @@ -10,6 +11,20 @@ namespace KCore.Extensions.InsteadSLThree { public static class SLThreeExtensions { + public static string ReadString(this Stream stream) + { + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd(); + } + } + public static string[] ReadStrings(this Stream stream) + { + using (var sr = new StreamReader(stream)) + { + return sr.ReadToEnd().Split(new string[1] { Environment.NewLine }, StringSplitOptions.None); + } + } public static string JoinIntoString(this IEnumerable e, string delim) { var g = e.GetEnumerator(); @@ -52,5 +67,21 @@ public static T MaxBy(this IEnumerable enumerable, Func sel var comp = Comparer.Default; return enumerable.Aggregate((max, x) => comp.Compare(selector(x), selector(max)) > 0 ? x : max); } + + public static IEnumerable Batch(this IEnumerable enumerable, int size) + { + var buf = new List(); + foreach (var elem in enumerable) + { + buf.Add(elem); + if (buf.Count == size) + { + yield return buf.ToArray(); + buf.Clear(); + } + } + if (buf.Count > 0) + yield return buf.ToArray(); + } } } diff --git a/KCore/Forms/Form.cs b/KCore/Forms/Form.cs index c28e0b5..86167ed 100644 --- a/KCore/Forms/Form.cs +++ b/KCore/Forms/Form.cs @@ -10,26 +10,26 @@ using KCore.Graphics; using KCore.Graphics.Widgets; using System.CodeDom.Compiler; +using KCore.Storage; +using KCore.Tools; namespace KCore { /// /// Базовый тип консольных окон /// - public abstract class Form + public abstract class Form : BasePanel { public Form() { Root = new RootWidget(this); } #region fields and vmethods - private bool status, allredraw, resize; + internal bool allredraw; - private bool clear; - - private int redrawersstart; + private bool status, resize; - private bool optimized = false; + private bool clear; private bool needshowing = false; @@ -94,33 +94,12 @@ protected virtual void OnResize() { } private TimeSpan LastEndExecuted; public TimeSpan RealUPS => LastEndExecuted - LastStartExecuted; - private List requestList = new List(); - private Request[] requests; - public Request[] Requests => requestList.ToArray(); private readonly Stopwatch stopwatch = new Stopwatch(); public Form Reference { get; set; } = null; - - private void Optimize() - { - if (requestList?.Count > 0) - { - requests = new Request[requestList.Count]; var index = 0; - - for (var i = 0; i < requestList.Count; i++) - if (!requestList[i].AllRedraw) requests[index++] = requestList[i]; - for (var i = 0; i < requestList.Count; i++) - if (requestList[i].AllRedraw) requests[index++] = requestList[i]; - - redrawersstart = Array.FindIndex(requests, x => x.AllRedraw); - if (redrawersstart == -1) redrawersstart = requests.Length; - } - else - { - requests = new Request[0]; - } - optimized = true; - } + public override Form GetBindingForm() => this; + public override bool AllRedraw => allredraw; + protected override IList GetPanelBinds() => requestList; public readonly RootWidget Root; /// @@ -128,40 +107,6 @@ private void Optimize() /// public IControlable ActiveWidget { get; set; } - #region Binds - public void Bind(Request request) - { - requestList.Add(request); - optimized = false; - } - public void Bind(params Request[] requests) - { - requestList.AddRange(requests); - optimized = false; - } - public void Bind(Widget widget) - { - requestList.AddRange(widget.InternalGetBinds(this)); - optimized = false; - } - public void Bind(params Widget[] widgets) - { - for (var i = 0; i < widgets.Length; i++) - requestList.AddRange(widgets[i].InternalGetBinds(this)); - optimized = false; - } - public void Unbind(Request request) - { - requestList.Remove(request); - optimized = false; - } - public void Unbind(Widget widget) - { - requestList.RemoveAll(x => x is Widget.IWidgetRequest wr && wr.Widget == widget); - optimized = false; - } - #endregion - #region Main Logic private void MainLoop(bool exit_after = true) { @@ -257,11 +202,11 @@ private void MainLoop(bool exit_after = true) } catch (ArgumentException e) when (e.TargetSite.Name == "SetCursorPosition") { - //resize = true; + Log.Add(e.ToString()); } catch (ArgumentOutOfRangeException e) when (e.TargetSite.Name == "SetBufferSize") { - //resize = true; + Log.Add(e.ToString()); } if (!needshowing && !Terminal.WindowIsActive) @@ -311,6 +256,7 @@ public void OneTimeDrawForRedirection() public void Start(bool redirected = false) { + KCoreStorage.Init(); if (!optimized) Optimize(); Terminal.AddKeyDown(OnKeyDown); @@ -332,6 +278,7 @@ public void Start(bool redirected = false) } catch (Exception e) { + Log.Add(e.ToString()); var ev = new ExceptionViewer(e, AllowedRestartAfterException); this.StartAnimation(ev); if (!ev.Restarted) status = false; @@ -480,10 +427,10 @@ public static void Abort() protected bool AllowedDashboard = AllowDashboardInAllForms; private static bool ManualStop = false; internal static string ConsoleShellTextLeft = "KCore " + Dashboard.Version.Major + "." + Dashboard.Version.Minor + " "; - const string ConsoleShellTextRight = "Dashboard: F12"; + internal static string ConsoleShellTextRight => Localization.Current["KCore_DASH"]; private static bool ManualRedraw = false; private static bool RaiseException = false; - private static bool ShowUPS = false; + internal static bool ShowUPS = false; public bool ManualLock = false; protected virtual bool IsRecursiveForm() => false; protected static Form ExceptionForm; @@ -491,13 +438,7 @@ public static void Abort() private static bool ActiveDashboard; private static void ConsoleShellActivate(byte x) { - if (x == Key.F7) - { - ShowUPS = !ShowUPS; - ManualRedraw = true; - } if (x == Key.F8) ManualRedraw = true; - //if (x == Key.F9) RaiseException = true; if (x == Key.F9) ManualStop = !ManualStop; if (x == Key.F10) ManualRedraw = true; if (x == Key.F12) ActiveDashboard = true; diff --git a/KCore/Forms/Request.cs b/KCore/Forms/Request.cs index 97c69d4..497a7d3 100644 --- a/KCore/Forms/Request.cs +++ b/KCore/Forms/Request.cs @@ -11,13 +11,14 @@ namespace KCore.Graphics [DebuggerDisplay("[{GetType().Name}]")] public abstract class Request { - private Form bindedTo; - public Form BindedTo => bindedTo; + private BasePanel bindedTo; + public BasePanel BindedTo => bindedTo; public virtual bool AllRedraw => false; + public abstract void Send(); public abstract void Cancel(); public abstract bool Condition(); public abstract void Invoke(); - public Request(Form form) + public Request(BasePanel form) { bindedTo = form; } @@ -26,9 +27,9 @@ public Request(Form form) public class Trigger : Request { private bool Request; - public Action
InvokeDelegate; + public Action InvokeDelegate; - public Trigger(Form form, Action invoke = null) : base(form) + public Trigger(BasePanel form, Action invoke = null) : base(form) { InvokeDelegate = invoke ?? (f => { }); } @@ -39,14 +40,15 @@ public override void Invoke() InvokeDelegate(BindedTo); Request = false; } - public void Do() => Request = true; + public void Pull() => Request = true; public override void Cancel() => Request = false; + public override void Send() => Request = true; } public class TriggerRedrawer : Trigger { - public TriggerRedrawer(Form form, Action invoke = null) + public TriggerRedrawer(Form form, Action invoke = null) : base(form, invoke) { @@ -56,7 +58,7 @@ public TriggerRedrawer(Form form, Action invoke = null) public class Redrawer : DelegateRequest { - public Redrawer(Form form, Func condition = null, Action invoke = null, Action cancel = null) + public Redrawer(Form form, Func condition = null, Action invoke = null, Action cancel = null) : base(form, condition, invoke, cancel) { @@ -66,11 +68,12 @@ public Redrawer(Form form, Func condition = null, Action invok public class DelegateRequest : Request { - public Action CancelDelegate = form => { }; - public Func ConditionDelegate = form => false; - public Action InvokeDelegate = form => { }; + public Action CancelDelegate = form => { }; + public Action RegisterDelegate = form => { }; + public Func ConditionDelegate = form => false; + public Action InvokeDelegate = form => { }; - public DelegateRequest(Form form, Func condition = null, Action invoke = null, Action cancel = null) : base(form) + public DelegateRequest(Form form, Func condition = null, Action invoke = null, Action cancel = null) : base(form) { ConditionDelegate = condition ?? (f => true); InvokeDelegate = invoke ?? (f => { }); @@ -80,5 +83,6 @@ public DelegateRequest(Form form, Func condition = null, Action ConditionDelegate(BindedTo); public override void Invoke() => InvokeDelegate(BindedTo); public override void Cancel() => CancelDelegate(BindedTo); + public override void Send() => RegisterDelegate(BindedTo); } } diff --git a/KCore/Graphics/Core/Chars.cs b/KCore/Graphics/Core/Chars.cs index c448318..660bc65 100644 --- a/KCore/Graphics/Core/Chars.cs +++ b/KCore/Graphics/Core/Chars.cs @@ -1,6 +1,8 @@ using KCore.Extensions; +using KCore.Extensions.InsteadSLThree; using KCore.Tools; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Reflection; @@ -8,7 +10,7 @@ namespace KCore.Graphics.Core { public static class Chars { - public static Dictionary MixingMultipliers { get; private set; } + public static readonly Dictionary MixingMultipliers; public static float GetMixingMultiplier(this char c) => MixingMultipliers.ContainsKey(c) ? MixingMultipliers[c] : 0; @@ -17,8 +19,8 @@ static Chars() var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream("KCore.lucida_mixmult.ini")) { - var ini = Inifile.ReadIniStream(stream); - MixingMultipliers = ini.Value["MAIN"].Keys.ToArray().ToDictionary(x => (char)x.ToInt32(), x => ini.Value["MAIN"][x].ToFloat()); + var ini = Initial.FromIniText(stream.ReadString()); + MixingMultipliers = ini["MAIN"].ToDictionary(x => (char)x.Key.ToInt32(), x => float.Parse(x.Value, CultureInfo.InvariantCulture)); } } } diff --git a/KCore/Graphics/Uncontrolable/Graph.cs b/KCore/Graphics/Uncontrolable/Graph.cs index 7580e25..233aa4e 100644 --- a/KCore/Graphics/Uncontrolable/Graph.cs +++ b/KCore/Graphics/Uncontrolable/Graph.cs @@ -493,6 +493,9 @@ internal static void FillRectangle(ConsoleColor color, int startleft, int startt Row(color, startleft, i, width); } + internal static void FillRectangle(ConsoleColor color, IContainer container) + => FillRectangle(color, container.Left, container.Top, container.Width, container.Height); + public static void ChooseEffect(ConsoleColor color, int startleft, int starttop, int width, int height) { Back = color; diff --git a/KCore/Graphics/Widgets/Canvas.cs b/KCore/Graphics/Widgets/Canvas.cs new file mode 100644 index 0000000..4a75347 --- /dev/null +++ b/KCore/Graphics/Widgets/Canvas.cs @@ -0,0 +1,33 @@ +using KCore.Graphics.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KCore.Graphics.Widgets +{ + public abstract class Canvas : Widget + { + public List NextHistory { get; set; } + public List PrevHistory { get; set; } + public int HistoryDepth { get; set; } = 256; + public bool SaveHistory { get; set; } = false; + + public ComplexPixel[,] AppliedCanvasMatrix { get; set; } + public ComplexPixel[,] CanvasMatrix { get; set; } + public Canvas() + { + + } + + public abstract void Prev(); + public abstract void Next(); + public abstract void LockRedrawing(); + public abstract void UnlockRerawing(); + public abstract void Set(int left, int top); + public abstract void Line(int left, int top, int right, int bottom); + public abstract void Text(string text); + public abstract void Char(char @char); + } +} diff --git a/KCore/Graphics/Widgets/Interfaces/IResizeble.cs b/KCore/Graphics/Widgets/Interfaces/IResizeble.cs new file mode 100644 index 0000000..355c361 --- /dev/null +++ b/KCore/Graphics/Widgets/Interfaces/IResizeble.cs @@ -0,0 +1,7 @@ +namespace KCore.Graphics +{ + public interface IResizeble + { + void Resize(); + } +} diff --git a/KCore/Graphics/Widgets/ListBox.cs b/KCore/Graphics/Widgets/ListBox.cs index facac50..2d3aea3 100644 --- a/KCore/Graphics/Widgets/ListBox.cs +++ b/KCore/Graphics/Widgets/ListBox.cs @@ -71,6 +71,7 @@ private class WidgetScrollUp : WidgetRequest public WidgetScrollUp(Form form, ListBox widget) : base(form, widget) { } public override bool Condition() => Widget.NeedScrollUp; public override void Cancel() => Widget.NeedScrollUp = false; + public override void Send() => Widget.NeedScrollUp = true; public override void Invoke() => Widget.ScrollUp(); } private class WidgetScrollDown : WidgetRequest @@ -78,6 +79,7 @@ private class WidgetScrollDown : WidgetRequest public WidgetScrollDown(Form form, ListBox widget) : base(form, widget) { } public override bool Condition() => Widget.NeedScrollDown; public override void Cancel() => Widget.NeedScrollDown = false; + public override void Send() => Widget.NeedScrollDown = true; public override void Invoke() => Widget.ScrollDown(); } private bool SelectingRedrawTrigger; @@ -89,6 +91,7 @@ public WidgetSelectingRedraw(Form form, ListBox widget) : base(form, widget) public override bool AllRedraw => true; public override void Cancel() => Widget.SelectingRedrawTrigger = false; + public override void Send() => Widget.SelectingRedrawTrigger = true; public override bool Condition() => Widget.SelectingRedrawTrigger; public override void Invoke() => Widget.SelectingRedraw(); } diff --git a/KCore/Graphics/Widgets/Panel.cs b/KCore/Graphics/Widgets/Panel.cs new file mode 100644 index 0000000..107a253 --- /dev/null +++ b/KCore/Graphics/Widgets/Panel.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static KCore.Graphics.Widget; + +namespace KCore.Graphics.Widgets +{ + public abstract class BasePanel + { + internal bool optimized = false; + internal int redrawersstart; + + public void Bind(Request request) + { + requestList.Add(request); + optimized = false; + } + public void Bind(params Request[] requests) + { + requestList.AddRange(requests); + optimized = false; + } + public void Bind(Widget widget) + { + requestList.AddRange(widget.InternalGetBinds(GetBindingForm())); + optimized = false; + } + public void Bind(params Widget[] widgets) + { + for (var i = 0; i < widgets.Length; i++) + requestList.AddRange(widgets[i].InternalGetBinds(GetBindingForm())); + optimized = false; + } + public void Bind(BasePanel panel) + { + requestList.AddRange(panel.GetPanelBinds()); + optimized = false; + } + public void Unbind(Request request) + { + requestList.Remove(request); + optimized = false; + } + public void Unbind(Widget widget) + { + requestList.RemoveAll(x => x is Widget.IWidgetRequest wr && wr.Widget == widget); + optimized = false; + } + public void Unbind(BasePanel panel) + { + if (panel is Form form) + { + foreach (var bind in form.GetPanelBinds()) + requestList.Remove(bind); + } + else requestList.RemoveAll(x => x is Panel.IPanelRequest pr && pr.Panel == panel); + optimized = false; + } + + internal List requestList = new List(); + internal Request[] requests; + public Request[] Requests => requestList.ToArray(); + protected abstract IList GetPanelBinds(); + public abstract Form GetBindingForm(); + public abstract bool AllRedraw { get; } + + public void Optimize() + { + if (requestList?.Count > 0) + { + requests = new Request[requestList.Count]; var index = 0; + + for (var i = 0; i < requestList.Count; i++) + if (!requestList[i].AllRedraw) requests[index++] = requestList[i]; + for (var i = 0; i < requestList.Count; i++) + if (requestList[i].AllRedraw) requests[index++] = requestList[i]; + + redrawersstart = Array.FindIndex(requests, x => x.AllRedraw); + if (redrawersstart == -1) redrawersstart = requests.Length; + } + else + { + requests = new Request[0]; + } + optimized = true; + } + } + + public class Panel : BasePanel, INestedWidgets, IResizeble + { + #region Visible (Hide + Show) + public bool Visible { get => visible; set { if (value) Show(); else Hide(); } } + public IList AreBelow { get; set; } = new Widget[0]; + + private bool visible = true; + private void MainHide() + { + HideTrigger = false; + if (!visible) return; + OnHiding?.Invoke(this); + visible = false; + foreach (var x in AreBelow) x.Redraw(); + } + private void MainShow() + { + ShowTrigger = false; + if (visible) return; + OnShowing?.Invoke(this); + visible = true; + } + #endregion + + #region Enabling + public bool Enabled { get => enabled; set { if (value) Enable(); else Disable(); } } + + private bool enabled = true; + private void MainEnable() + { + EnableTrigger = false; + if (enabled) return; + OnEnabling?.Invoke(this); + enabled = true; + } + private void MainDisable() + { + DisableTrigger = false; + if (!enabled) return; + OnDisabling?.Invoke(this); + enabled = false; + } + #endregion + + #region Requests + public interface IPanelRequest + { + Panel Panel { get; } + } + + [DebuggerDisplay("[{Panel.GetType().Name,nq}] {GetType().Name.Replace(\"Panel\", \"\"),nq}")] + public abstract class PanelRequest : Request, IPanelRequest where T : Panel + { + public T Panel; + public PanelRequest(T panel) : base(panel.BindedTo) + { + Panel = panel; + } + + Panel IPanelRequest.Panel => Panel; + } + + private sealed class PanelRequests : PanelRequest + { + public PanelRequests(Panel panel) : base(panel) { } + public override void Send() { } + public override void Cancel() { } + public override bool Condition() => Panel.Enabled; + public override void Invoke() + { + if (!Panel.Enabled) return; + for (var i = 0; i < Panel.redrawersstart; i++) + { + if (Panel.requests[i].Condition()) + Panel.requests[i].Invoke(); + } + } + } + private sealed class PanelRedrawers : PanelRequest + { + public PanelRedrawers(Panel panel) : base(panel) { } + public override bool AllRedraw => true; + public override void Send() { } + public override void Cancel() { } + public override bool Condition() => Panel.Visible; + public override void Invoke() + { + if (!Panel.Visible) return; + for (var i = Panel.redrawersstart; i < Panel.requests.Length; i++) + { + if (Panel.BindedTo.allredraw || Panel.requests[i].Condition()) + Panel.requests[i].Invoke(); + } + } + } + private sealed class PanelHide : PanelRequest + { + public PanelHide(Panel panel) : base(panel) { } + public override bool Condition() => Panel.HideTrigger; + public override void Send() => Panel.HideTrigger = true; + public override void Cancel() => Panel.HideTrigger = false; + public override void Invoke() => Panel.MainHide(); + } + private sealed class PanelShow : PanelRequest + { + public PanelShow(Panel panel) : base(panel) { } + public override bool Condition() => Panel.ShowTrigger; + public override void Send() => Panel.ShowTrigger = true; + public override void Cancel() => Panel.ShowTrigger = false; + public override void Invoke() => Panel.MainShow(); + } + private sealed class PanelEnable : PanelRequest + { + public PanelEnable(Panel panel) : base(panel) { } + public override bool Condition() => Panel.EnableTrigger; + public override void Send() => Panel.EnableTrigger = true; + public override void Cancel() => Panel.EnableTrigger = false; + public override void Invoke() => Panel.MainEnable(); + } + private sealed class PanelDisable : PanelRequest + { + public PanelDisable(Panel panel) : base(panel) { } + public override bool Condition() => Panel.DisableTrigger; + public override void Send() => Panel.DisableTrigger = true; + public override void Cancel() => Panel.DisableTrigger = false; + public override void Invoke() => Panel.MainDisable(); + } + #endregion + + #region Triggers + private bool HideTrigger; + private bool ShowTrigger; + private bool EnableTrigger; + private bool DisableTrigger; + #endregion + + #region Events + public event Action OnHiding; + public event Action OnShowing; + public event Action OnEnabling; + public event Action OnDisabling; + public event Action OnResizing; + #endregion + + #region Atomic requests + private void Hide() + { + HideTrigger = true; + } + private void Show() + { + ShowTrigger = true; + } + private void Enable() + { + EnableTrigger = true; + } + private void Disable() + { + DisableTrigger = true; + } + #endregion + + protected override IList GetPanelBinds() + { + return new Request[] + { + new PanelRequests(this), + new PanelRedrawers(this), + new PanelHide(this), + new PanelShow(this), + new PanelEnable(this), + new PanelDisable(this), + }; + } + + public Panel(Form form) + { + BindedTo = form; + } + public Form BindedTo { get; set; } + public override bool AllRedraw => BindedTo.AllRedraw; + protected List Childs { get; set; } = new List(); + public Widget[] GetChilds() => Childs.ToArray(); + + public void AddWidget(Widget widget) + { + Childs.Add(widget); + Bind(widget); + Optimize(); + } + public void RemoveWidget(Widget widget) + { + Childs.Remove(widget); + Unbind(widget); + Optimize(); + } + public void ClearWidgets(Predicate predicate) + { + var i = 0; + while (i < Childs.Count) + { + if (predicate(Childs[i])) + { + Unbind(Childs[i]); + Childs.RemoveAt(i); + } + else i++; + } + Optimize(); + } + public void ClearWidgets() + { + for (var i = 0; i < Childs.Count; i++) + Unbind(Childs[i]); + Childs.Clear(); + Optimize(); + } + + public override Form GetBindingForm() => BindedTo; + + public void Resize() + { + var count = Childs.Count; + for (var i = 0; i < count; i++) + Childs[i].Resize(); + OnResizing?.Invoke(this); + } + } +} diff --git a/KCore/Graphics/Widgets/RootWidget.cs b/KCore/Graphics/Widgets/RootWidget.cs index 5c14f13..fa8db9f 100644 --- a/KCore/Graphics/Widgets/RootWidget.cs +++ b/KCore/Graphics/Widgets/RootWidget.cs @@ -7,7 +7,8 @@ namespace KCore.Graphics public class RootWidget : Widget, INestedWidgets { public readonly Form Form; - internal List Childs { get; set; } = new List(); + protected List Childs { get; set; } = new List(); + public Widget[] GetChilds() => Childs.ToArray(); internal RootWidget(Form form) : base(0, 0, null, LeftUpAlignment, true, true) diff --git a/KCore/Graphics/Widgets/Text/ScrollableText.cs b/KCore/Graphics/Widgets/Text/ScrollableText.cs index 7f8773c..e5ab198 100644 --- a/KCore/Graphics/Widgets/Text/ScrollableText.cs +++ b/KCore/Graphics/Widgets/Text/ScrollableText.cs @@ -90,6 +90,7 @@ private class WidgetScrollUp : WidgetRequest { public WidgetScrollUp(Form form, ScrollableText widget) : base(form, widget) { } + public override void Send() => Widget.NeedScrollUp = true; public override void Cancel() => Widget.NeedScrollUp = false; public override bool Condition() => Widget.Visible && Widget.NeedScrollUp; @@ -103,6 +104,7 @@ private class WidgetScrollDown : WidgetRequest { public WidgetScrollDown(Form form, ScrollableText widget) : base(form, widget) { } + public override void Send() => Widget.NeedScrollDown = true; public override void Cancel() => Widget.NeedScrollDown = false; public override bool Condition() => Widget.Visible && Widget.NeedScrollDown; @@ -116,14 +118,15 @@ private class WidgetAutoscroll : WidgetRequest { public WidgetAutoscroll(Form form, ScrollableText widget) : base(form, widget) { } + public override void Send() => Widget.NeedScrollDown = true; public override void Cancel() => Widget.NeedScrollDown = false; - public override bool Condition() => Widget.Visible && Widget.Autoscroll && BindedTo.FormTimer >= (Widget.lastAutoscroll + Widget.AutoscrollInterval); + public override bool Condition() => Widget.Visible && Widget.Autoscroll && (BindedTo as Form).FormTimer >= (Widget.lastAutoscroll + Widget.AutoscrollInterval); public override void Invoke() { Widget.NeedScrollUp = true; - Widget.lastAutoscroll = BindedTo.FormTimer; + Widget.lastAutoscroll = (BindedTo as Form).FormTimer; } } diff --git a/KCore/Graphics/Widgets/Widget.cs b/KCore/Graphics/Widgets/Widget.cs index 2d3134d..bb788eb 100644 --- a/KCore/Graphics/Widgets/Widget.cs +++ b/KCore/Graphics/Widgets/Widget.cs @@ -13,10 +13,11 @@ namespace KCore.Graphics { - public abstract class Widget : BoundedObject + + public abstract class Widget : BoundedObject, IResizeble { public Widget( - int left = 0, int top = 0, IContainer container = null, Alignment? alignment = null, bool fillWidth = true, bool fillHeight = true) + int left = 0, int top = 0, IContainer container = null, Alignment? alignment = null, bool fillWidth = true, bool fillHeight = true) : base(left, top, container, alignment, fillWidth, fillHeight) { @@ -29,7 +30,7 @@ public interface IWidgetRequest } [DebuggerDisplay("[{Widget.GetType().Name,nq}] {GetType().Name.Replace(\"Widget\", \"\"),nq}")] - public abstract class WidgetRequest : Request, IWidgetRequest where T: Widget + public abstract class WidgetRequest : Request, IWidgetRequest where T : Widget { public T Widget; public WidgetRequest(Form form, T widget) : base(form) @@ -45,6 +46,7 @@ public WidgetRedraw(Form form, Widget widget) : base(form, widget) { } public override bool AllRedraw => true; public override bool Condition() => Widget.RedrawTrigger; + public override void Send() => Widget.RedrawTrigger = true; public override void Cancel() => Widget.RedrawTrigger = false; public override void Invoke() => Widget.MainRedraw(); } @@ -52,6 +54,7 @@ private sealed class WidgetReclear : WidgetRequest { public WidgetReclear(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.ReclearTrigger; + public override void Send() => Widget.ReclearTrigger = true; public override void Cancel() => Widget.ReclearTrigger = false; public override void Invoke() => Widget.MainReclear(); } @@ -59,6 +62,7 @@ private sealed class WidgetHide : WidgetRequest { public WidgetHide(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.HideTrigger; + public override void Send() => Widget.HideTrigger = true; public override void Cancel() => Widget.HideTrigger = false; public override void Invoke() => Widget.MainHide(); } @@ -66,6 +70,7 @@ private sealed class WidgetShow : WidgetRequest { public WidgetShow(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.ShowTrigger; + public override void Send() => Widget.ShowTrigger = true; public override void Cancel() => Widget.ShowTrigger = false; public override void Invoke() => Widget.MainShow(); } @@ -73,6 +78,7 @@ private sealed class WidgetEnable : WidgetRequest { public WidgetEnable(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.EnableTrigger; + public override void Send() => Widget.EnableTrigger = true; public override void Cancel() => Widget.EnableTrigger = false; public override void Invoke() => Widget.MainEnable(); } @@ -80,6 +86,7 @@ private sealed class WidgetDisable : WidgetRequest { public WidgetDisable(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.DisableTrigger; + public override void Send() => Widget.DisableTrigger = true; public override void Cancel() => Widget.DisableTrigger = false; public override void Invoke() => Widget.MainDisable(); } @@ -87,6 +94,7 @@ private sealed class WidgetSelect : WidgetRequest { public WidgetSelect(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.SelectTrigger; + public override void Send() => Widget.SelectTrigger = true; public override void Cancel() => Widget.SelectTrigger = false; public override void Invoke() => Widget.MainSelect(); } @@ -94,6 +102,7 @@ private sealed class WidgetDeselect : WidgetRequest { public WidgetDeselect(Form form, Widget widget) : base(form, widget) { } public override bool Condition() => Widget.DeselectTrigger; + public override void Send() => Widget.DeselectTrigger = true; public override void Cancel() => Widget.DeselectTrigger = false; public override void Invoke() => Widget.MainDeselect(); } diff --git a/KCore/KCore.csproj b/KCore/KCore.csproj index 700ac11..92d73ef 100644 --- a/KCore/KCore.csproj +++ b/KCore/KCore.csproj @@ -63,9 +63,13 @@ + + + - + + @@ -88,6 +92,7 @@ + @@ -95,15 +100,20 @@ - + + + - + + + + diff --git a/KCore/Properties/AssemblyInfo.cs b/KCore/Properties/AssemblyInfo.cs index de7609b..43b4df5 100644 --- a/KCore/Properties/AssemblyInfo.cs +++ b/KCore/Properties/AssemblyInfo.cs @@ -66,10 +66,10 @@ public Reflected() } public const string Major = "0"; //vh - public const string Minor = "1"; //vh + public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "545"; //vh - public const long LastUpdate = 638379725215808805; //vh + public const string Revision = "880"; //vh + public const long LastUpdate = 638396998308191773; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/KCore/Refactoring/KCoreDataFile.cs b/KCore/Refactoring/KCoreDataFile.cs new file mode 100644 index 0000000..ac342e6 --- /dev/null +++ b/KCore/Refactoring/KCoreDataFile.cs @@ -0,0 +1,124 @@ +using KCore.Extensions; +using KCore.Graphics.Core; +using KCore.Tools; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.ComTypes; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Text; +using System.Threading.Tasks; +using static KCore.Refactoring.KCoreDataFiles; + +namespace KCore.Refactoring +{ + public interface IKCoreDataFile + { + FileInfo ReadedFileInfo { get; } + KCoreFileSpecification Specification { get; } + KCoreDataFiles.KCoreDataFile Data { get; } + } + + public static class KCoreDataFile + { + public class PrimitiveFile : IKCoreDataFile + { + public FileInfo ReadedFileInfo { get; private set; } + public PrimitiveSpecification Specification { get; private set; } + public PrimitiveData Data { get; private set; } + + KCoreFileSpecification IKCoreDataFile.Specification => Specification; + KCoreDataFiles.KCoreDataFile IKCoreDataFile.Data => Data; + } + } + + public static class KCoreDataFiles + { + + public enum DataType + { + Unknown, + Primitive, + Charitive, + Complexive, + Videoxive, + } + + + public abstract class KCoreFileSpecification + { + public abstract DataType DataType { get; } + public Version KCoreVersion { get; protected set; } + public int DataFormatVersion { get; protected set; } + + internal static KCoreFileSpecification GetObject(DataType dataType) + { + switch (dataType) + { + case DataType.Primitive: return new PrimitiveSpecification(); + } + throw new ArgumentException("Unsupported", nameof(dataType)); + } + internal static KCoreFileSpecification Read(Initial initial) + { + var ini = initial["Specification"]; + var dt = ini["Type"].ToEnum(); + var ret = GetObject(dt); + ret.KCoreVersion = new Version(ini["KCoreVersion"]); + ret.DataFormatVersion = ini["DataFormatVersion"].ToInt32(); + ret.AdditionalRead(ini); + return ret; + } + internal Initial Write() + { + var ret = new Initial(); + var ini = ret["Specification"]; + ini["Type"] = DataType.ToString(); + ini["KCoreVersion"] = global::KCoreVersion.Version; + ini["DataFormatVersion"] = DataFormatVersion.ToString(); + AdditionalWrite(ini); + return ret; + } + protected virtual void AdditionalRead(Initial.IniSection ini) { } + protected virtual void AdditionalWrite(Initial.IniSection ini) { } + } + public abstract class KCoreDataFile + { + public byte[] Data { get; protected set; } + internal static KCoreDataFile GetObject(DataType dataType) + { + switch (dataType) + { + case DataType.Primitive: return new PrimitiveData(); + } + throw new ArgumentException("Unsupported", nameof(dataType)); + } + } + public class UnknownSpecification : KCoreFileSpecification + { + public override DataType DataType => DataType.Unknown; + internal UnknownSpecification() { } + } + public class PrimitiveSpecification : KCoreFileSpecification + { + public override DataType DataType => DataType.Primitive; + public int Width { get; private set; } + public int Height { get; private set; } + protected override void AdditionalRead(Initial.IniSection ini) + { + Width = ini["Width"].ToInt32(); + Height = ini["Height"].ToInt32(); + } + protected override void AdditionalWrite(Initial.IniSection ini) + { + ini["Width"] = Width.ToString(); + ini["Height"] = Height.ToString(); + } + } + public class PrimitiveData : KCoreDataFile + { + public Primitive Primitive { get; set; } + } + } +} diff --git a/KCore/Graphics/Refactoring/SuperText.cs b/KCore/Refactoring/SuperText.cs similarity index 100% rename from KCore/Graphics/Refactoring/SuperText.cs rename to KCore/Refactoring/SuperText.cs diff --git a/KCore/Refactoring/Test.cs b/KCore/Refactoring/Test.cs new file mode 100644 index 0000000..40c718f --- /dev/null +++ b/KCore/Refactoring/Test.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace KCore.Refactoring +{ + public static class Test + { + public static void DoAll() + { + KCore.Graphics.Core.Chars.GetMixingMultiplier('c'); + } + } +} diff --git a/KCore/TerminalCore/Terminal.cs b/KCore/TerminalCore/Terminal.cs index ba166a6..db2e19e 100644 --- a/KCore/TerminalCore/Terminal.cs +++ b/KCore/TerminalCore/Terminal.cs @@ -1,4 +1,5 @@ -using KCore.CoreForms; +using KCore.Storage; +using KCore.CoreForms; using KCore.Graphics; using KCore.Graphics.Core; using KCore.TerminalCore; @@ -13,6 +14,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Runtime.Remoting.Metadata.W3cXsd2001; namespace KCore { @@ -38,27 +40,12 @@ public static class Terminal private static int cached_ups = 70; private static void ManualTools(byte x) { - if (x == Key.F2) WindowSizeExternalManage = !WindowSizeExternalManage; - if (x == Key.F4) FixedWindowWidth++; - if (x == Key.F6) FixedWindowHeight++; - if (x == Key.F3 && FixedWindowWidth > minimalWindowWidth) FixedWindowWidth--; - if (x == Key.F5 && FixedWindowHeight > minimalWindowHeight) FixedWindowHeight--; - if (x == Key.F8) - { - if (UpdatesPerSecond == 0) UpdatesPerSecond = cached_ups; - else - { - cached_ups = UpdatesPerSecond; - UpdatesPerSecond = 0; - } - } } private static void UpKeyMethod(byte x) { } internal static Thread KeyThread { get; set; } - private static int keywait = 20; - private static int keysplit = 3; + private static int keywait = 20, keysplit = 3; private static bool onlyOneRepeation = true; public static bool OnlyOneRepeation { get => onlyOneRepeation; set => onlyOneRepeation = value; } @@ -80,8 +67,10 @@ public static int KeySplit } } + //public static bool KeyRestrictedPerfomance { get => restrictedPerfomance; set => restrictedPerfomance = value; } + private static bool KeyThreadLoop = true; - private static bool RestrictedPerfomance = true; + private static bool restrictedPerfomance = true; private static void KeyProcessor() { var pressed_keys = new int[256]; @@ -139,6 +128,7 @@ public static void Abort() KeyThreadLoop = false; Thread.Sleep(500); KeyThread.Abort(); + Tools.Log.Abort(); OnKeyDown -= ManualTools; OnKeyUp -= UpKeyMethod; } @@ -412,7 +402,7 @@ public static void ResetFore() Fore = Theme.Fore; } - public static void Init() => Init(50, 15); + public static void Init() => Init(80, 25); public static void Init(int width, int height) { diff --git a/KCore/TerminalCore/TerminalBase.cs b/KCore/TerminalCore/TerminalBase.cs index c6e6f10..2ac9ef9 100644 --- a/KCore/TerminalCore/TerminalBase.cs +++ b/KCore/TerminalCore/TerminalBase.cs @@ -82,7 +82,14 @@ internal static CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo() static TerminalBase() { - Console.CursorVisible = false; + try + { + Console.CursorVisible = false; + } + catch + { + + } CachedOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); } } diff --git a/KCore/Tools/Inifile.cs b/KCore/Tools/Inifile.cs deleted file mode 100644 index 494a85e..0000000 --- a/KCore/Tools/Inifile.cs +++ /dev/null @@ -1,385 +0,0 @@ -using KCore.Extensions; -using System; -using System.Collections.Generic; -using System.IO; - -namespace KCore.Tools -{ - public class Inifile - { - public Dictionary> Value { get; set; } = new Dictionary>(); - internal Dictionary, string[]> Commentaries { get; set; } = new Dictionary<(string, string), string[]>(); - internal List CurrentComment { get; set; } = new List(); - - private Inifile() - { - Value = new Dictionary>(); - } - - private string currentsection = null; - - public bool SaveInfo { get; set; } = true; - - public string CurrentSection - { - get - { - return currentsection; - } - set - { - CheckOnContains(value); - currentsection = value; - } - } - - public int Version { get; set; } = 0; - - public Dictionary CurrentKeyValue { get => Value[CurrentSection]; set => Value[CurrentSection] = value; } - - - private void CheckOnContains(string value) - { - if (!Value.ContainsKey(value)) Value.Add(value, new Dictionary()); - } - - private void CheckOnContainsWithThrow(string section, string key) - { - if (!Value.ContainsKey(section)) throw new KeyNotFoundException(); - if (!Value[section].ContainsKey(key)) throw new KeyNotFoundException(); - } - - private void CheckOnContainsWithThrow(string key) - { - if (!Value[CurrentSection].ContainsKey(key)) throw new KeyNotFoundException(); - } - - public bool Contains(string section, string key) - { - return Value[section].ContainsKey(key); - } - - public bool Contains(string key) - { - return Value[CurrentSection].ContainsKey(key); - } - - public string ReadString(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key]; - } - - public string ReadString(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key]; - } - - public bool ReadBool(string section, string key) - { - CheckOnContainsWithThrow(section, key); - if (bool.TryParse(Value[section][key], out var result)) return result; - else return Value[section][key].ToInt32() != 0; - } - - public bool ReadBool(string key) - { - CheckOnContainsWithThrow(key); - if (bool.TryParse(Value[CurrentSection][key], out var result)) return result; - else return Value[CurrentSection][key].ToInt32() != 0; - } - - public byte ReadByte(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToByte(); - } - - public byte ReadByte(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToByte(); - } - - public sbyte ReadSByte(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToSByte(); - } - - public sbyte ReadSByte(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToSByte(); - } - - public short ReadInt16(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToInt16(); - } - - public short ReadInt16(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToInt16(); - } - - public ushort ReadUInt16(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToUInt16(); - } - - public ushort ReadUInt16(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToUInt16(); - } - - public int ReadInt32(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToInt32(); - } - - public int ReadInt32(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToInt32(); - } - - public uint ReadUInt32(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToUInt32(); - } - - public uint ReadUInt32(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToUInt32(); - } - - public long ReadInt64(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToInt64(); - } - - public long ReadInt64(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToInt64(); - } - - public ulong ReadUInt64(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToUInt64(); - } - - public ulong ReadUInt64(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToUInt64(); - } - - public float ReadFloat(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToFloat(); - } - - public float ReadFloat(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToFloat(); - } - - public double ReadDouble(string section, string key) - { - CheckOnContainsWithThrow(section, key); - return Value[section][key].ToDouble(); - } - - public double ReadDouble(string key) - { - CheckOnContainsWithThrow(key); - return Value[CurrentSection][key].ToDouble(); - } - - public void WriteComment(string section, string key, string[] text) - { - if (Commentaries.ContainsKey((section, key))) Commentaries[(section, key)] = text; - else Commentaries.Add((section, key), text); - } - - public void WriteComment(string section, string key, string text) - { - if (Commentaries.ContainsKey((section, key))) Commentaries[(section, key)] = new string[1] { text }; - else Commentaries.Add((section, key), new string[1] { text }); - } - - public void WriteComment(string text) - { - CurrentComment.Add(text); - } - - public void WriteComment(string[] text) - { - CurrentComment.AddRange(text); - } - - public void WriteSectionComment(string section, string text) - { - WriteComment(section, "", text); - } - - public void WriteSectionComment(string text) - { - WriteComment(CurrentSection, "", text); - } - - public void WriteSectionComment(string section, string[] text) - { - WriteComment(section, "", text); - } - - public void WriteSectionComment(string[] text) - { - WriteComment(CurrentSection, "", text); - } - - public void Write(string section, string key, T o) - { - if (CurrentComment.Count > 0) - { - WriteComment(section, key, CurrentComment.ToArray()); - CurrentComment.Clear(); - } - CheckOnContains(section); - if (Value[section].ContainsKey(key)) Value[section][key] = o.ToString(); - else Value[section].Add(key, o.ToString()); - } - - public void Write(string key, T o) - { - if (CurrentComment.Count > 0) - { - WriteComment(CurrentSection, key, CurrentComment.ToArray()); - CurrentComment.Clear(); - } - if (Value[CurrentSection].ContainsKey(key)) Value[CurrentSection][key] = o.ToString(); - else Value[CurrentSection].Add(key, o.ToString()); - } - - public static Inifile AppendIniFile(string filename) => File.Exists(filename) ? ReadIniFile(filename) : Create(); - - public static Inifile Create() => new Inifile(); - - public static Inifile ReadIniText(string[] text) - { - var Result = new Inifile(); - - var CurrentBlock = "INIFILE"; - - for (var i = 0; i < text.Length; i++) - { - if (!string.IsNullOrWhiteSpace(text[i]) && !text[i].Trim().StartsWith(";")) - { - var x = text[i].Trim(); - - if (x.StartsWith("[") && x.EndsWith("]")) - { - CurrentBlock = x.Substring(1, x.Length - 2); - if (!Result.Value.ContainsKey(CurrentBlock)) Result.Value.Add(CurrentBlock, new Dictionary()); - } - else - { - var splitter = x.IndexOf('='); - - var key = x.Substring(0, splitter); - - var value = x.Substring(splitter + 1, x.Length - key.Length - 1); - - Result.Value[CurrentBlock].Add(key, value); - } - } - else if (text[i].StartsWith("; $Version")) - { - var splitter = text[i].IndexOf('='); - Result.Version = text[i].Substring(splitter + 1, text[i].Length - splitter - 1).ToInt32(); - } - } - - return Result; - } - - public static Inifile ReadIniFile(string filename) - { - return ReadIniText(File.ReadAllLines(filename)); - } - - internal static string[] ReadStrings(Stream stream) - { - using (var sr = new StreamReader(stream)) - { - return sr.ReadToEnd().Split(new string[1] { Environment.NewLine }, StringSplitOptions.None); - } - } - - public static Inifile ReadIniStream(Stream stream) - { - return ReadIniText(ReadStrings(stream)); - } - - public void WriteIniFile(string filename) - { - var sb = new System.Text.StringBuilder(); - if (Value.Count > 0) - { - if (SaveInfo) - { - sb.AppendLine("; Autogenerated .ini file"); - sb.AppendLine("; This file generated in KCore"); - } - if (Version != 0) sb.AppendLine($"; $Version = {Version}"); - var dt = DateTime.Now; - if (SaveInfo) - { - sb.AppendLine($"; Last update {dt.ToShortDateString()} {dt.ToLongTimeString()}"); - } - if (Version != 0 || SaveInfo) sb.AppendLine(); - } - var sections = Value.Keys; - var id = 0; - foreach (var section in sections) - { - var keys = Value[section].Keys; - var sectiontuple = (section, ""); - if (Commentaries.ContainsKey(sectiontuple)) - { - for (var i = 0; i < Commentaries[sectiontuple].Length; i++) - sb.AppendLine($"; {Commentaries[sectiontuple][i]}"); - } - sb.AppendLine($"[{section}]"); - foreach (var key in keys) - { - var value = Value[section][key]; - var tuple = (section, key); - if (Commentaries.ContainsKey(tuple)) - { - for (var i = 0; i < Commentaries[tuple].Length; i++) - sb.AppendLine($"; {Commentaries[tuple][i]}"); - } - sb.AppendLine($"{key}={value}"); - } - if (id != sections.Count - 1) sb.AppendLine(); - id++; - } - File.WriteAllText(filename, sb.ToString()); - } - } -} diff --git a/KCore/Tools/Initial.cs b/KCore/Tools/Initial.cs new file mode 100644 index 0000000..47cca38 --- /dev/null +++ b/KCore/Tools/Initial.cs @@ -0,0 +1,171 @@ +using KCore.Extensions; +using KCore.Extensions.InsteadSLThree; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace KCore.Tools +{ + public class Initial : IEnumerable>> + { + private Dictionary> Data; + + public struct IniSection : IEnumerable> + { + private Initial Reference; + public readonly string SectionName; + public string this[string index] + { + get => Reference.Data[SectionName].TryGetValue(index, out var value) ? value : null; + set => Reference.Data[SectionName][index] = value?.ToString() ?? ""; + } + public bool TryGetValue(string index, out string value) + { + var val = this[index]; + value = null; + if (val == null) return false; + value = val.ToString(); + return true; + } + + private static IEnumerable GetMembers(Type type, BindingFlags addition) + { + //public get+set properties + //public non-readonly fields + foreach (var x in type.GetProperties(BindingFlags.Public | addition | BindingFlags.SetProperty | BindingFlags.GetProperty)) + if (x.GetIndexParameters().Length == 0) + yield return x; + foreach (var x in type.GetFields(BindingFlags.Public | addition | BindingFlags.SetField | BindingFlags.GetField)) + yield return x; + } + private void InternalSerialize(object o, Type type, BindingFlags addition) + { + foreach (var x in GetMembers(type, addition)) + { + if (x is PropertyInfo pi) + this[pi.Name] = pi.GetValue(o)?.ToString(); + if (x is FieldInfo fi) + this[fi.Name] = fi.GetValue(o)?.ToString(); + } + } + public void Serialize(object o) + { + if (o == null) return; + InternalSerialize(o, o.GetType(), BindingFlags.Instance); + } + public void SerializeStatic(Type type) + { + InternalSerialize(null, type, BindingFlags.Static); + } + + public IniSection(Initial inifile, string section) + { + Reference = inifile; + SectionName = section; + if (!inifile.Data.ContainsKey(section)) inifile.Data.Add(section, new Dictionary()); + } + + public IEnumerator> GetEnumerator() + { + return Reference.Data[SectionName].GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + public Initial() + { + Data = new Dictionary>(); + } + + public IniSection this[string index] + { + get => new IniSection(this, index); + } + + public static bool DefaultSaveInfo { get; set; } = true; + public bool SaveInfo { get; set; } = DefaultSaveInfo; + public static bool DefaultSaveInfoGeneration { get; set; } = false; + public bool SaveInfoGeneration { get; set; } = DefaultSaveInfoGeneration; + public string[] SaveInfoText { get; set; } = new string[0]; + + public string ToIniText() + { + var sb = new System.Text.StringBuilder(); + if (SaveInfo) + { + if (SaveInfoGeneration) + { + sb.AppendLine("; This file generated with KCore"); + var dt = DateTime.Now; + sb.AppendLine($"; Last update {dt:dd.MM.yyyy} {dt:H:mm:ss}"); + sb.AppendLine(); + } + if (SaveInfoText.Length > 0) + sb.AppendLine(SaveInfoText.Select(x => "; " + x).JoinIntoString("\n")); + } + sb.AppendLine(this.Select(section => $"[{section.Key}]\n{section.Value.Select(pair => $"{pair.Key}={pair.Value}").JoinIntoString("\n")}").JoinIntoString("\n")); + return sb.ToString(); + } + public static Initial FromIniText(string all) + { + var Result = new Initial(); + var text = all.Split(Environment.NewLine.ToCharArray()); + Result.Data[""] = new Dictionary(); + + var CurrentSection = ""; + + for (var i = 0; i < text.Length; i++) + { + var x = text[i].Trim(); + if (!string.IsNullOrWhiteSpace(x) && !x.StartsWith(";")) + { + + if (x.StartsWith("[") && x.EndsWith("]")) + { + CurrentSection = x.Substring(1, x.Length - 2); + if (!Result.Data.ContainsKey(CurrentSection)) Result.Data.Add(CurrentSection, new Dictionary()); + } + else + { + var splitter = x.IndexOf('='); + + var key = x.Substring(0, splitter); + + var value = x.Substring(splitter + 1, x.Length - key.Length - 1); + + Result.Data[CurrentSection][key] = value; + } + } + } + + return Result; + } + + public static void Test() + { + var ini = new Initial(); + var section = ini["Section"]; + section["x"] = "2"; + var x = section["x"]; + section.SerializeStatic(typeof(Console)); + File.WriteAllText("test_ini.ini", ini.ToIniText()); + var ini2 = Initial.FromIniText(File.ReadAllText("test_ini.ini")); + } + + public IEnumerator>> GetEnumerator() + { + return Data.GetEnumerator(); + } + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/KCore/Tools/Log.cs b/KCore/Tools/Log.cs index 666c145..6a4a4a0 100644 --- a/KCore/Tools/Log.cs +++ b/KCore/Tools/Log.cs @@ -30,27 +30,14 @@ public static class Log public static string GetString(this DateTime dt) { - var sb = new StringBuilder(); - sb.Append(dt.Day.ToString().PadLeft(2, '0')); sb.Append('.'); - sb.Append(dt.Month.ToString().PadLeft(2, '0')); sb.Append('.'); - sb.Append(dt.Year.ToString()); sb.Append(' '); - sb.Append(dt.Hour.ToString().PadLeft(2, '0')); sb.Append(':'); - sb.Append(dt.Minute.ToString().PadLeft(2, '0')); sb.Append(':'); - sb.Append(dt.Second.ToString().PadLeft(2, '0')); sb.Append(':'); - sb.Append(dt.Millisecond.ToString().PadLeft(3, '0')); - return sb.ToString(); + return dt.ToString("dd.MM.yyyy HH:mm:ss:fff"); } - public static void SdkCommand(bool b) => IsInSDK = b; - static bool IsInSDK = Assembly.GetEntryAssembly() != null && Assembly.GetEntryAssembly().GetName().Name == "BikerSDK"; - public static void Save() { lock (locker) { -#if !DEBUG if (!File.Exists(LogFileName)) File.Create(LogFileName).Close(); -#endif Append(queue.ToArray().JoinIntoString("")); queue.Clear(); } @@ -58,9 +45,7 @@ public static void Save() public static void Abort() { -#if DEBUG if (LogThread != null && LogThread.IsAlive) LogThread.Abort(); -#endif } public static void LogProcessor() @@ -76,28 +61,17 @@ internal static void Init() { lock (locker) { -#if DEBUG LogThread = new Thread(LogProcessor); LogThread.Name = "Log thread"; LogThread.Start(); - File.Create(LogFileName).Close(); -#else if (File.Exists(LogFileName)) File.Delete(LogFileName); -#endif + File.Create(LogFileName).Close(); init = true; } } - internal static void ConWrite(string s) - { - if (s.Contains("Exception: ")) System.Console.ForegroundColor = ConsoleColor.Red; - System.Console.WriteLine(s); - System.Console.ResetColor(); - } - internal static void Append(string s) { - if (IsInSDK) ConWrite(s); File.AppendAllText(LogFileName, s); } diff --git a/KCore/__/KCoreStorage.cs b/KCore/__/KCoreStorage.cs new file mode 100644 index 0000000..6124e47 --- /dev/null +++ b/KCore/__/KCoreStorage.cs @@ -0,0 +1,514 @@ +using KCore.CoreForms; +using KCore.Extensions; +using KCore.Extensions.InsteadSLThree; +using KCore.Graphics; +using KCore.Graphics.Containers; +using KCore.Graphics.Widgets; +using KCore.Tools; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Text; +using System.Threading.Tasks; +using static KCore.CoreForms.Dashboard.Settings; +using static KCore.Storage.KCoreStorage; + +namespace KCore.Storage +{ + public static class KCoreStorage + { + private const string PortablePath = "KCore.portable"; + private const string RunInformationFile = "runinfo.ini"; + private const string ConfigPath = "KCore.ini"; + + public const string KCoreLINK = "github.com/AIexandrKotov/KCore"; + public static string EntryLINK = "Undefined"; + + public static string GetApplicationPath() => Path.Combine(KCorePath, "Applications", Assembly.GetEntryAssembly().GetCustomAttribute().Title); + public static string GetLocalConfigPath() => Path.Combine(GetApplicationPath(), ConfigPath); + public static string GetGlobalConfigPath() => Path.Combine(KCorePath, ConfigPath); + public static bool Portable { get; private set; } + public static string KCorePath { get; private set; } = ""; + public static readonly string KCoreLibPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName); + + public class WelcomeForm : Form + { + public ListBox Actions; + public Trigger EnterTrigger; + public Trigger LanguageTrigger; + + #region Data + + public bool Installed = false; + public Choise? Return = null; + public string InstallationPath = null; + public enum Choise + { + PortableMode, + InstallationMode + } + #endregion + + private void ReinitActions() + { + if (Installed) + { + Actions.Childs = new List() + { + new ListBox.ListItem(new TextWidget(Localization.Current["Welcome_Next"], fillHeight: false)), + new ListBox.ListItem(new TextWidget(Localization.Current["Welcome_ForcePortable"], fillHeight: false)), + }; + } + else + { + Actions.Childs = new List() + { + new ListBox.ListItem(new TextWidget(Localization.Current["Welcome_Portable"], fillHeight: false)), + new ListBox.ListItem(new TextWidget(Localization.Current["Welcome_Intall"], fillHeight: false)), + }; + } + Actions.Container = new DynamicContainer() + { + GetLeft = () => (Terminal.FixedWindowWidth - 40) / 2, + GetTop = () => 7, + GetHeight = () => 5, + GetWidth = () => 40 + }; + Actions.Resize(); + } + + public WelcomeForm(bool installed = false) + { + AllowedDashboard = false; + + Installed = installed; + Actions = new ListBox(); + ReinitActions(); + + + ActiveWidget = Actions; + Root.AddWidget(Actions); + Bind(EnterTrigger = new Trigger(this, form => (form as WelcomeForm).Enter(Actions.Position))); + Bind(LanguageTrigger = new Trigger(this, form => + { + Localization.Next(); + (form as WelcomeForm).ReinitActions(); + (form as Form).Clear(); + })); + } + + public void Enter(int position) + { + if (Installed) + { + switch (position) + { + case 0: + Close(); + return; + case 1: + Return = Choise.PortableMode; + Close(); + return; + + } + } + else + { + switch (position) + { + case 0: + Return = Choise.PortableMode; + Close(); + return; + case 1: + InstallationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Games", "KCore"); + Return = Choise.InstallationMode; + Close(); + return; + + } + } + } + + private static void WelcomeRedraw(string start, int count) + { + for (var i = 0; i < count; i++) + { + Terminal.Set(0, 2 + i); + Localization.Current[start + i.ToString()] + .Replace("%Title%", Assembly.GetEntryAssembly().GetCustomAttribute().Title) + .PrintSuperText(null, TextAlignment.Center); + } + } + + protected override void OnAllRedraw() + { + base.OnAllRedraw(); + if (Installed) + WelcomeRedraw("Welcome_I", 3); + else + WelcomeRedraw("Welcome_U", 4); + Terminal.Set(1, Terminal.FixedWindowHeight - 4); + (Localization.Current["Welcome_Lang"] + $" ({Localization.Current.LocalName})").PrintSuperText(); + + Terminal.Set(1, Terminal.FixedWindowHeight - 2); + var entry_assembly = Assembly.GetEntryAssembly(); + var assembly_name = entry_assembly.GetName(); + var name = assembly_name.Name; + var version = assembly_name.Version; + var version_str = $"{version.Major}.{version.Minor}.{version.Build}"; + var entry_copyright = entry_assembly.GetCustomAttribute().Copyright; + string.Format(Localization.Current["Welcome_EntryBy"], name, version_str, entry_copyright, EntryLINK).PrintSuperText(); + + Terminal.Set(1, Terminal.FixedWindowHeight - 1); + string.Format(Localization.Current["Welcome_KCoreBy"], KCoreVersion.Name, KCoreVersion.VersionWithoutRevision, KCoreVersion.Copyright, KCoreLINK).PrintSuperText(); + } + + protected override void OnKeyDown(byte key) + { + if (key == Key.E || key == Key.Enter) + EnterTrigger.Pull(); + if (key == Key.LeftAlt || key == Key.RightAlt) + LanguageTrigger.Pull(); + base.OnKeyDown(key); + } + } + + public static void Install() + { + Update(); + } + + private static string[] directories = new string[] + { + "Localizations.", + }; + + public static void Update() + { + foreach (var x in directories) + { + Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine(KCorePath, x.Replace(".", "\\")))); + } + foreach (var x in Assembly.GetExecutingAssembly().GetManifestResourceNames().Where(x => x.StartsWith("KCore.__."))) + { + var info = Assembly.GetExecutingAssembly().GetManifestResourceInfo(x); + var sub_path = x.Replace("KCore.__.", ""); + var cur_dir = directories.FirstOrDefault(dir => sub_path.StartsWith(dir)); + if (cur_dir != null) + sub_path = sub_path.Replace(cur_dir, cur_dir.Replace(".", "\\")); + using (var fileStream = File.Create(Path.Combine(KCorePath, sub_path))) + { + Assembly.GetExecutingAssembly().GetManifestResourceStream(x).CopyTo(fileStream); + } + } + } + + public static void Run() + { + File.WriteAllText(Path.Combine(KCorePath, RunInformationFile), RunInformation.This.Write().ToIniText()); + } + + + public abstract class Configuration + { + public abstract void Apply(); + public abstract Initial Save(); + } + + public class GlobalConfig : Configuration + { + public string Language; + + public GlobalConfig(bool init = true) + { + if (init) + { + Language = Localization.Current.Name; + } + } + + public static GlobalConfig Read(Initial ini) + { + var ret = new GlobalConfig(false); + var kcore = ini["KCore"]; + ret.Language = kcore["Language"]; + return ret; + } + + public override void Apply() + { + var ind = Array.FindIndex(Localization.Localizations, x => x.Name == Language); + if (ind != -1) Localization.Current = Localization.Localizations[ind]; + } + + public override Initial Save() + { + var ini = new Initial(); + var kcore = ini["KCore"]; + kcore["Language"] = Language; + return ini; + } + } + + public class LocalConfig : Configuration + { + public bool AllowExternal; + public (int, int) WindowSize; + public int UpdatePerSecond; + public bool TransitionAnimations; + public int AnimationSpeed; + + public LocalConfig(bool init = true) + { + if (init) + { + AllowExternal = Terminal.WindowSizeExternalManage; + WindowSize = (Terminal.FixedWindowWidth, Terminal.FixedWindowHeight); + UpdatePerSecond = Terminal.UpdatesPerSecond; + TransitionAnimations = GraphicsExtensions.AllowTransitionAnimations; + AnimationSpeed = GraphicsExtensions.TransitionAnimationsSpeed; + } + } + + public static LocalConfig Read(Initial ini) + { + var ret = new LocalConfig(false); + var kcore = ini["KCore"]; + ret.AllowExternal = kcore["AllowExternal"].ToBool(); + var ws = kcore["WindowSize"].Split('x'); + ret.WindowSize = (ws[0].ToInt32(), ws[1].ToInt32()); + ret.UpdatePerSecond = kcore["UpdatePerSecond"].ToInt32(); + ret.TransitionAnimations = kcore["TransitionAnimations"].ToBool(); + ret.AnimationSpeed = kcore["AnimationSpeed"].ToInt32(); + return ret; + } + + public override void Apply() + { + Terminal.WindowSizeExternalManage = false; + (Terminal.FixedWindowWidth, Terminal.FixedWindowHeight) = WindowSize; + Terminal.Resize(); + Terminal.WindowSizeExternalManage = AllowExternal; + Terminal.UpdatesPerSecond = UpdatePerSecond; + GraphicsExtensions.AllowTransitionAnimations = TransitionAnimations; + GraphicsExtensions.TransitionAnimationsSpeed = AnimationSpeed; + } + + public override Initial Save() + { + var ini = new Initial(); + var kcore = ini["KCore"]; + kcore["AllowExternal"] = Terminal.WindowSizeExternalManage.ToString(); + kcore["WindowSize"] = $"{Terminal.FixedWindowWidth}x{Terminal.FixedWindowHeight}"; + kcore["UpdatePerSecond"] = Terminal.UpdatesPerSecond.ToString(); + kcore["TransitionAnimations"] = GraphicsExtensions.AllowTransitionAnimations.ToString(); + kcore["AnimationSpeed"] = GraphicsExtensions.TransitionAnimationsSpeed.ToString(); + return ini; + } + } + + public class RunInformation + { + public static RunInformation This = Create(); + + public int Revision; + public Version Version; + + public Initial Write() + { + var ret = new Initial(); + var main = ret[""]; + + main["Revision"] = Revision.ToString(); + main["Version"] = $"{Version.Major}.{Version.Minor}.{Version.Build}"; + + return ret; + } + + public static RunInformation Read(string path) + { + var ret = new RunInformation(); + + var ini = Initial.FromIniText(File.ReadAllText(path)); + var main = ini[""]; + + ret.Revision = int.Parse(main["Revision"]); + var ver = main["Version"].Split('.').ConvertAll(x => int.Parse(x)); + ret.Version = new Version(ver[0], ver[1], ver[2]); + + return ret; + } + + public static RunInformation Create() + { + return new RunInformation() + { + Revision = Dashboard.Version.Revision, + Version = new Version(Dashboard.Version.Major, Dashboard.Version.Minor, Dashboard.Version.Build) + }; + } + } + + public static bool NewerInstalled { get; private set; } + + public static bool NeedToUpdate() + { + var ripath = Path.Combine(KCorePath, RunInformationFile); + if (File.Exists(ripath)) + { + var ri = RunInformation.Read(ripath); + NewerInstalled = ri.Version > RunInformation.This.Version; + return RunInformation.This.Revision > ri.Revision; + } + else + { + Directory.CreateDirectory(Path.GetDirectoryName(ripath)); + File.WriteAllText(ripath, RunInformation.This.Write().ToIniText()); + return true; + } + } + + public static bool NeedToInstall { get; set; } = false; + + public static void InitAsPortable() + { + File.WriteAllText(Path.Combine(KCoreLibPath, PortablePath), "This file makes KCore portable"); + Portable = true; + KCorePath = Path.Combine(KCoreLibPath, "KCore"); + NeedToInstall = true; + Directory.CreateDirectory(GetApplicationPath()); + } + public static void InitAsInstallation(string path) + { + Portable = false; + KCorePath = path; + Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Console", true).CreateSubKey("KCore").SetValue("Storage", KCorePath); + NeedToInstall = true; + Directory.CreateDirectory(GetApplicationPath()); + } + + private static bool inited = false; + + private static void Welcome(bool installed = false) + { + var welcome = new WelcomeForm(installed); + welcome.Start(); + if (!installed) + { + if (welcome.Return == WelcomeForm.Choise.PortableMode) + InitAsPortable(); + else if (welcome.Return == WelcomeForm.Choise.InstallationMode) + InitAsInstallation(welcome.InstallationPath); + else return; + } + else + { + if (welcome.Return == WelcomeForm.Choise.PortableMode) + InitAsPortable(); + else Directory.CreateDirectory(GetApplicationPath()); + } + } + + public static void InitGlobalConfig() + { + var global_config = GetGlobalConfigPath(); + if (File.Exists(global_config)) + GlobalConfig.Read(Initial.FromIniText(File.ReadAllText(global_config))).Apply(); + else SaveGlobalConfig(); + } + + public static void InitLocalConfig() + { + var local_config = GetLocalConfigPath(); + if (File.Exists(local_config)) + LocalConfig.Read(Initial.FromIniText(File.ReadAllText(local_config))).Apply(); + else SaveLocalConfig(); + } + + public static void SaveGlobalConfig() + { + File.WriteAllText(GetGlobalConfigPath(), new GlobalConfig().Save().ToIniText()); + } + + public static void SaveLocalConfig() + { + File.WriteAllText(GetLocalConfigPath(), new LocalConfig().Save().ToIniText()); + } + + public static void Init() + { + if (inited) return; + Localization.InitDefault(); + inited = true; + Portable = File.Exists(Path.Combine(KCoreLibPath, PortablePath)); + if (Portable) + { + KCorePath = Path.Combine(KCoreLibPath, "KCore"); + if (NeedToUpdate()) + Update(); + InitGlobalConfig(); + Localization.InitStorage(); + InitLocalConfig(); + if (!NewerInstalled) Run(); + } + else + { + var kcore = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Console").OpenSubKey("KCore"); + if (kcore == null) + { + Welcome(); + if (NeedToInstall) + Install(); + else if (NeedToUpdate()) + Update(); + InitGlobalConfig(); + Localization.InitStorage(); + InitLocalConfig(); + if (!NewerInstalled) Run(); + } + else + { + KCorePath = kcore.GetValue("Storage").Cast(); + if (!Directory.Exists(KCorePath)) + { + Welcome(); + if (NeedToInstall) + Install(); + else if (NeedToUpdate()) + Update(); + if (!NewerInstalled) Run(); + InitGlobalConfig(); + Localization.InitStorage(); + InitLocalConfig(); + } + else if (!Directory.Exists(GetApplicationPath())) + { + if (NeedToUpdate()) + Update(); + InitGlobalConfig(); + Localization.InitStorage(); + if (!NewerInstalled) Run(); + Welcome(true); + InitLocalConfig(); + } + else + { + if (NeedToUpdate()) + Update(); + InitGlobalConfig(); + Localization.InitStorage(); + InitLocalConfig(); + if (!NewerInstalled) Run(); + } + } + } + } + + } +} diff --git a/KCore/__/Localization.cs b/KCore/__/Localization.cs new file mode 100644 index 0000000..843df8e --- /dev/null +++ b/KCore/__/Localization.cs @@ -0,0 +1,83 @@ +using KCore.Extensions.InsteadSLThree; +using KCore.Tools; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Security.Permissions; +using System.Text; +using System.Threading.Tasks; + +namespace KCore.Storage +{ + public sealed class Localization + { + private Dictionary Data; + public string this[string text] => Data.TryGetValue(text, out var value) ? value : text; + + public readonly string Name; + public readonly string LocalName; + + private static readonly Localization EnglishLocalization; + public static Localization[] Localizations = new Localization[0]; + public static Localization Current { get; set; } + + public static void Next() + { + var ind = Array.IndexOf(Localizations, Current); + ind++; + if (ind >= Localizations.Length) ind = 0; + Current = Localizations[ind]; + } + public static void Prev() + { + var ind = Array.IndexOf(Localizations, Current); + ind--; + if (ind < 0) ind = Localizations.Length - 1; + Current = Localizations[ind]; + } + + private Localization() + { + Name = "English"; + LocalName = "English"; + Data = Initial.FromIniText(KCoreAssembly.GetManifestResourceStream("KCore.__.Localizations.en.ini").ReadString())[""].ToDictionary(x => x.Key, x => x.Value); + } + + public Localization(Initial initial) + { + var info = initial["INFO"]; + Name = info["Name"]; + LocalName = info["LocalName"]; + + Data = initial[""].ToDictionary(x => x.Key, x => x.Value); + + foreach (var x in EnglishLocalization.Data) + if (!Data.ContainsKey(x.Key)) Data.Add(x.Key, x.Value); + } + + static Localization() + { + EnglishLocalization = new Localization(); + } + static Assembly KCoreAssembly = Assembly.GetExecutingAssembly(); + + internal static void InitDefault() + { + Localizations = KCoreAssembly.GetManifestResourceNames().Where(x => x.StartsWith("KCore.__.Localizations.")).Select(x => new Localization(Initial.FromIniText(KCoreAssembly.GetManifestResourceStream(x).ReadString()))).ToArray(); + Current = Localizations[0]; + } + + public static void InitStorage() + { + var Localizations = Directory.GetFiles(Path.Combine(KCoreStorage.KCorePath, "Localizations"), "*.ini").Select(x => new Localization(Initial.FromIniText(File.ReadAllText(x)))).ToArray(); + var ind = Array.FindIndex(Localizations, x => x.Name == Current?.Name); + if (Localizations.Length != 0) + Localization.Localizations = Localizations; + if (ind != -1) Current = Localizations[ind]; + } + } +} diff --git a/KCore/__/Localizations/en.ini b/KCore/__/Localizations/en.ini new file mode 100644 index 0000000..4755ebe --- /dev/null +++ b/KCore/__/Localizations/en.ini @@ -0,0 +1,67 @@ +; When creating a localization +; keep in mind that the console supports a limited set of characters +; you can watch them with Palette in KCore Dashboard + +[INFO] +Name=English +LocalName=English + +[] +KCore_Resizing1=You are resizing the console window +KCore_Resizing2=Going back via {0:0.0} +KCore_DASH=Dashboard: F12 +KCore_DASH_Close=Close: F12 + +Welcome_U0=Welcome! +Welcome_U1=You have launched %=>Red%%Title%%=>reset% for the first time +Welcome_U2=%=>Red%%Title%%=>reset% uses %=>Blue%KCore%=>reset% +Welcome_U3=You need to choose its placement +Welcome_I0=Welcome! +Welcome_I1=You have launched %=>Red%%Title%%=>reset% for the first time +Welcome_I2=Thanks for using KCore! +Welcome_Next=Next +Welcome_Portable=%=>Magenta%Portable using%=>reset% +Welcome_ForcePortable=%=>Magenta%Force portable using%=>reset% +Welcome_Intall=%=>Blue%Install KCore%=>reset% +Welcome_Lang=%=>Gray back% Alt %=>reset back% Language +Welcome_KCoreBy=%=>Blue%{0}%=>reset% {1} by {2} (%=>Blue%{3}%=>reset%) +Welcome_EntryBy=%=>Red%{0}%=>reset% {1} by {2} (%=>Blue%{3}%=>reset%) + +DASH_PN_Settings=SETTINGS +DASH_PN_FormInfo=FORM +DASH_PN_Version=VERSION +DASH_PN_Palette=PALETTE + +DASH_Enabled=Enabled +DASH_Disabled=Disabled + +DASH_MAIN=_MAIN_ +DASH_Language=KCore Language +DASH_GRAPHICS=_GRAPHICS_ +DASH_ConsoleSize=Console size +DASH_MakeMaximal=Make maximal size +DASH_MakeMinimal=Make minimal size +DASH_ExternalResizing=External resizing +DASH_UpdatesPerSec=Updates per sec +DASH_TransitionAnimations=Transition animations +DASH_TransitionAnimationSpeed=TA Speed +DASH_ADVANCED=_ADVANCED_SETTINGS_ +DASH_CurrentApplication=Current application +DASH_Portable=Portable +DASH_Common=Common +DASH_ShowUPS=Show UPS +DASH_Unlimited=Unlimited + +DASH_PaletteInfo=List of allowed characters +DASH_VersionUndefined=Developer of %=>Red%{0}%=>reset% did not specify a list of changes +DASH_KCoreBy=%=>Blue%{0}%=>reset% {1} by {2}\n%=>Blue%{3}%=>reset% +DASH_EntryBy=%=>Red%{0}%=>reset% {1} by {2}\n%=>Blue%{3}%=>reset% + +DASH_F_Current=Current +DASH_F_StartedFrom=Started from +DASH_F_FormTimer=Form timer +DASH_F_Delay=Delay +DASH_F_sec=s +DASH_F_msec=ms +DASH_F_Total=Total Redrawers/Requests +DASH_F_RootWidgets=Root widgets \ No newline at end of file diff --git a/KCore/__/Localizations/ru.ini b/KCore/__/Localizations/ru.ini new file mode 100644 index 0000000..6d7e6b3 --- /dev/null +++ b/KCore/__/Localizations/ru.ini @@ -0,0 +1,67 @@ +; Создавая локализацию +; имейте ввиду, что консоль поддерживает ограниченный набор символов +; вы можете посмотреть их в палитре в Dashboard KCore + +[INFO] +Name=Russian +LocalName=Русский + +[] +KCore_Resizing1=Изменение размера консоли +KCore_Resizing2=Возвращение назад через {0:0.0} +KCore_DASH=Панель: F12 +KCore_DASH_Close=Закрыть: F12 + +Welcome_U0=Добро пожаловать! +Welcome_U1=Вы впервые запустили %=>Red%%Title%%=>reset% +Welcome_U2=%=>Red%%Title%%=>reset% использует %=>Blue%KCore%=>reset% +Welcome_U3=Выберите расположение +Welcome_I0=Добро пожаловать! +Welcome_I1=Вы впервые запустили %=>Red%%Title%%=>reset% +Welcome_I2=Спасибо, что используете KCore! +Welcome_Next=Далее +Welcome_Portable=%=>Magenta%Портативное использование%=>reset% +Welcome_ForcePortable=%=>Magenta%Принудительно портативное%=>reset% +Welcome_Intall=%=>Blue%Установить KCore%=>reset% +Welcome_Lang=%=>Gray back% Alt %=>reset back% Язык +Welcome_KCoreBy=%=>Blue%{0}%=>reset% {1} от {2} (%=>Blue%{3}%=>reset%) +Welcome_EntryBy=%=>Red%{0}%=>reset% {1} от {2} (%=>Blue%{3}%=>reset%) + +DASH_PN_Settings=НАСТРОЙКИ +DASH_PN_FormInfo=ФОРМА +DASH_PN_Version=ВЕРСИЯ +DASH_PN_Palette=ПАЛИТРА + +DASH_Enabled=Включено +DASH_Disabled=Выключено + +DASH_MAIN=_ОСНОВНОЕ_ +DASH_Language=Язык KCore +DASH_GRAPHICS=_ГРАФИКА_ +DASH_ConsoleSize=Размер консоли +DASH_MakeMaximal=Сделать максимальным +DASH_MakeMinimal=Сделать минимальным +DASH_ExternalResizing=Внешнее изменение размера +DASH_UpdatesPerSec=Частота обновлений +DASH_TransitionAnimations=Анимации перехода +DASH_TransitionAnimationSpeed=Скорость анимаций +DASH_ADVANCED=_РАСШИРЕННЫЕ_НАСТРОЙКИ_ +DASH_CurrentApplication=Текущее приложение +DASH_Portable=Портативное +DASH_Common=Основное +DASH_ShowUPS=Показывать частоту обновлений +DASH_Unlimited=Неограничено + +DASH_PaletteInfo=Перечень допустимых символов +DASH_VersionUndefined=Разработчик %=>Red%{0}%=>reset% не описал список изменений +DASH_KCoreBy=%=>Blue%{0}%=>reset% {1} от {2}\n%=>Blue%{3}%=>reset% +DASH_EntryBy=%=>Red%{0}%=>reset% {1} от {2}\n%=>Blue%{3}%=>reset% + +DASH_F_Current=Текущая +DASH_F_StartedFrom=Запущена из +DASH_F_FormTimer=Таймер формы +DASH_F_Delay=Пауза +DASH_F_sec=с +DASH_F_msec=мс +DASH_F_Total=Всего Redrawer'ов/Request'ов +DASH_F_RootWidgets=Корневые виджеты \ No newline at end of file diff --git a/KCore/docs/versions/0.2.0 b/KCore/docs/versions/0.2.0 new file mode 100644 index 0000000..f8cee78 --- /dev/null +++ b/KCore/docs/versions/0.2.0 @@ -0,0 +1,8 @@ +------ KCore 0.2.0 ------ [01.01.24] +Main: + - New DASHBOARD + - Storage for KCore applications + - Localizations (en, ru) + - Inifile -> Initial +New widgets: + - Panel (Form is also Panel) \ No newline at end of file diff --git a/KCore/lucida_mixmult.ini b/KCore/lucida_mixmult.ini index e05f7f0..230f2a0 100644 --- a/KCore/lucida_mixmult.ini +++ b/KCore/lucida_mixmult.ini @@ -534,7 +534,7 @@ 8222=0.0875 8224=0.2125 8225=0.25 -8226=0.13125 +; 8226=0.13125 8240=0.34375 8249=0.0875 8250=0.075 diff --git a/Runner/Form1.cs b/Runner/Form1.cs index eea6af7..3277634 100644 --- a/Runner/Form1.cs +++ b/Runner/Form1.cs @@ -29,13 +29,13 @@ public Form1() }; TextInput.Activate(TextRow.Text); - Bind(CloseTrigger = new Trigger(this, form => form.Close())); + Bind(CloseTrigger = new Trigger(this, form => (form as Form).Close())); } protected override void OnKeyDown(byte key) { base.OnKeyDown(key); - if (key == Key.Tab || key == Key.Escape) CloseTrigger.Do(); + if (key == Key.Tab || key == Key.Escape) CloseTrigger.Pull(); } } } diff --git a/Runner/Form2.cs b/Runner/Form2.cs index de8e884..81f09a4 100644 --- a/Runner/Form2.cs +++ b/Runner/Form2.cs @@ -40,7 +40,7 @@ public Form2() box.AddWidget(new Window(fillWidth: true, fillHeight: true, child: box2, borderColor: ConsoleColor.Red)); box.AddWidget(box3); - Bind(CloseTrigger = new Trigger(this, form => form.Close())); + Bind(CloseTrigger = new Trigger(this, form => (form as Form).Close())); } protected override void OnAllRedraw() @@ -51,7 +51,7 @@ protected override void OnAllRedraw() protected override void OnKeyDown(byte key) { base.OnKeyDown(key); - if (key == Key.Tab || key == Key.Escape) CloseTrigger.Do(); + if (key == Key.Tab || key == Key.Escape) CloseTrigger.Pull(); } } } diff --git a/Runner/Form3.cs b/Runner/Form3.cs index 5c2e285..1e398a7 100644 --- a/Runner/Form3.cs +++ b/Runner/Form3.cs @@ -42,13 +42,13 @@ public Form3() Root.AddWidget(Window); Root.AddWidget(Text); - Bind(CloseTrigger = new Trigger(this, form => form.Close())); + Bind(CloseTrigger = new Trigger(this, form => (form as Form).Close())); } protected override void OnKeyDown(byte key) { base.OnKeyDown(key); - if (key == Key.Tab || key == Key.Escape) CloseTrigger.Do(); + if (key == Key.Tab || key == Key.Escape) CloseTrigger.Pull(); else if (key == Key.Spacebar) { var nv = !Text.Visible; diff --git a/Runner/Form4.cs b/Runner/Form4.cs index 121b71d..1c429d2 100644 --- a/Runner/Form4.cs +++ b/Runner/Form4.cs @@ -44,13 +44,13 @@ public Form4() ActiveWidget = List; - Bind(CloseTrigger = new Trigger(this, form => form.Close())); + Bind(CloseTrigger = new Trigger(this, form => (form as Form).Close())); } protected override void OnKeyDown(byte key) { base.OnKeyDown(key); - if (key == Key.Tab || key == Key.Escape) CloseTrigger.Do(); + if (key == Key.Tab || key == Key.Escape) CloseTrigger.Pull(); } } } diff --git a/Runner/Program.cs b/Runner/Program.cs index 01517eb..2ab679c 100644 --- a/Runner/Program.cs +++ b/Runner/Program.cs @@ -14,6 +14,7 @@ namespace Runner public class Choosing : Form { public ListBox List; + public Trigger CloseTrigger; public Trigger EnterTrigger; public static Type[] Forms; @@ -45,7 +46,8 @@ public Choosing() Root.AddWidget(wvs); Root.AddWidget(List); Root.AddWidget(wvs.Scroll); - Bind(EnterTrigger = new Trigger(this, form => form.RealizeAnimation(Activator.CreateInstance(Forms[List.Position]) as Form))); + Bind(CloseTrigger = new Trigger(this, form => { if ((form as Form).Reference?.GetType() == typeof(Choosing)) (form as Form).Close(); })); + Bind(EnterTrigger = new Trigger(this, form => (form as Form).RealizeAnimation(Activator.CreateInstance(Forms[List.Position]) as Form))); wnd.Resize(); ActiveWidget = List; @@ -54,7 +56,8 @@ public Choosing() protected override void OnKeyDown(byte key) { base.OnKeyDown(key); - if (key == Key.Enter || key == Key.E) EnterTrigger.Do(); + if (key == Key.Enter || key == Key.E) EnterTrigger.Pull(); + if (key == Key.Escape || key == Key.Tab) CloseTrigger.Pull(); } } diff --git a/Runner/Runner.csproj b/Runner/Runner.csproj index 77917fd..674ae5d 100644 --- a/Runner/Runner.csproj +++ b/Runner/Runner.csproj @@ -49,6 +49,7 @@ + diff --git a/Runner/Test.cs b/Runner/Test.cs new file mode 100644 index 0000000..e46b892 --- /dev/null +++ b/Runner/Test.cs @@ -0,0 +1,29 @@ +using KCore; +using KCore.Extensions.InsteadSLThree; +using KCore.Graphics.Widgets; +using KCore.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Runner +{ + public class Test : Form + { + public Trigger CloseTrigger; + + public Test() + { + Bind(CloseTrigger = new Trigger(this, form => (form as Form).Close())); + KCore.Refactoring.Test.DoAll(); + } + + protected override void OnKeyDown(byte key) + { + base.OnKeyDown(key); + if (key == Key.Tab || key == Key.Escape) CloseTrigger.Pull(); + } + } +} diff --git a/building/IncEditorRevision.bat b/building/IncEditorRevision.bat new file mode 100644 index 0000000..7f4a226 --- /dev/null +++ b/building/IncEditorRevision.bat @@ -0,0 +1 @@ +"../building/vh.exe" "../Editor/Properties/AssemblyInfo.cs" "revision++" \ No newline at end of file