From b48ed479a0909f9dc83f9b649550abc1ba9197e6 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 23 Apr 2021 00:17:46 +0200 Subject: [PATCH] streamlined TextInputWrapper into MlemPlatform and included link opening --- Demos.Android/Activity1.cs | 10 +- Demos.DesktopGL/Program.cs | 2 +- Docs/articles/ui.md | 17 +- .../MLEM.Templates.DesktopGL/Program.cs | 2 +- MLEM.Ui/Elements/Element.cs | 4 +- MLEM.Ui/Elements/Paragraph.cs | 2 +- MLEM.Ui/Elements/TextField.cs | 6 +- MLEM.Ui/UiSystem.cs | 11 +- MLEM/MLEM.csproj | 2 +- MLEM/Misc/MlemPlatform.cs | 188 ++++++++++++ MLEM/Misc/TextInputWrapper.cs | 280 ------------------ Sandbox/Program.cs | 2 +- 12 files changed, 211 insertions(+), 315 deletions(-) create mode 100644 MLEM/Misc/MlemPlatform.cs delete mode 100644 MLEM/Misc/TextInputWrapper.cs diff --git a/Demos.Android/Activity1.cs b/Demos.Android/Activity1.cs index 39139b6..0ec0e94 100644 --- a/Demos.Android/Activity1.cs +++ b/Demos.Android/Activity1.cs @@ -30,16 +30,12 @@ namespace Demos.Android { if (Build.VERSION.SdkInt >= BuildVersionCodes.P) this.Window.Attributes.LayoutInDisplayCutoutMode = LayoutInDisplayCutoutMode.ShortEdges; - TextInputWrapper.Current = new TextInputWrapper.Mobile(KeyboardInput.Show); + MlemPlatform.Current = new MlemPlatform.Mobile(KeyboardInput.Show, l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l)))); this.game = new GameImpl(); // reset MlemGame width and height to use device's aspect ratio this.game.GraphicsDeviceManager.ResetWidthAndHeight(this.game.Window); - this.game.OnLoadContent += game => { - // disable mouse handling for android to make emulator behavior more coherent - game.InputHandler.HandleMouse = false; - // make text links be opened properly - game.UiSystem.LinkBehavior = l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l.Match.Groups[1].Value))); - }; + // disable mouse handling for android to make emulator behavior more coherent + this.game.OnLoadContent += game => game.InputHandler.HandleMouse = false; // set the game to fullscreen to cause the status bar to be hidden this.game.GraphicsDeviceManager.IsFullScreen = true; this.view = this.game.Services.GetService(typeof(View)) as View; diff --git a/Demos.DesktopGL/Program.cs b/Demos.DesktopGL/Program.cs index 5ad71f6..952fb10 100644 --- a/Demos.DesktopGL/Program.cs +++ b/Demos.DesktopGL/Program.cs @@ -5,7 +5,7 @@ namespace Demos.DesktopGL { public static class Program { public static void Main() { - TextInputWrapper.Current = new TextInputWrapper.DesktopGl((w, c) => w.TextInput += c); + MlemPlatform.Current = new MlemPlatform.DesktopGl((w, c) => w.TextInput += c); using var game = new GameImpl(); game.Run(); } diff --git a/Docs/articles/ui.md b/Docs/articles/ui.md index c1e78e1..74dbc1c 100644 --- a/Docs/articles/ui.md +++ b/Docs/articles/ui.md @@ -36,24 +36,23 @@ protected override void Draw(GameTime gameTime) { ### Text Input On desktop devices, MonoGame provides the `Window.TextInput` event that gets called automatically with the correct characters for the keys that you're pressing, even for non-American keyboards. However, this function doesn't exist on other devices. Similarly, MonoGame provides the `KeyboardInput` class for showing an on-screen keyboard on mobile devices and consoles, but not on desktop. -To make MLEM.Ui compatible with all devices without publishing a separate version for each MonoGame platform, you have to set up the text input wrapper yourself, based on the system you're using MLEM.Ui with. This has to be done *before* initializing your `UiSystem`. +To make MLEM compatible with all devices without publishing a separate version for each MonoGame platform, you have to set up the `MlemPlatform` class based on the system you're using MLEM.Ui with. This has to be done *before* initializing your `UiSystem`. DesktopGL: ```cs -TextInputWrapper.Current = new TextInputWrapper.DesktopGl((w, c) => w.TextInput += c); +MlemPlatform.Current = new MlemPlatform.DesktopGl((w, c) => w.TextInput += c); ``` Mobile devices and consoles: ```cs -TextInputWrapper.Current = new TextInputWrapper.Mobile(KeyboardInput.Show); +MlemPlatform.Current = new MlemPlatform.Mobile(KeyboardInput.Show, l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l)))); ``` -Other systems. Note that, for this implementation, its `Update()` method also has to be called every game update tick. It only supports an American keyboard layout due to the way that it is implemented: +If you're not using text input, you can just set the platform to a stub one like so: ```cs -TextInputWrapper.Current = new TextInputWrapper.Primitive(); -``` -If you're not using text input, you can just set the wrapper to a stub one like so: -```cs -TextInputWrapper.Current = new TextInputWrapper.None(); +MlemPlatform.Current = new MlemPlatform.None(); ``` +Initializing the platform in this way also allows for links in paragraphs to be clickable, causing a browser or explorer window to be opened on desktop or mobile devices. + +For more info on MLEM's platform-related code, you can also check out MlemPlatform's [documentation](https://mlem.ellpeck.de/api/MLEM.Misc.MlemPlatform). ## Setting the style By default, MLEM.Ui's controls look pretty bland, since it doesn't ship with any fonts or textures for any of its controls. To change the style of your ui, simply expand your `new UntexturedStyle(this.SpriteBatch)` call to include fonts and textures of your choosing, for example: diff --git a/MLEM.Templates/content/MLEM.Templates.DesktopGL/Program.cs b/MLEM.Templates/content/MLEM.Templates.DesktopGL/Program.cs index bd48aeb..86307c9 100644 --- a/MLEM.Templates/content/MLEM.Templates.DesktopGL/Program.cs +++ b/MLEM.Templates/content/MLEM.Templates.DesktopGL/Program.cs @@ -5,7 +5,7 @@ namespace TemplateNamespace { public static class Program { public static void Main() { - TextInputWrapper.Current = new TextInputWrapper.DesktopGl((w, c) => w.TextInput += c); + MlemPlatform.Current = new MlemPlatform.DesktopGl((w, c) => w.TextInput += c); using var game = new GameImpl(); game.Run(); } diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 23d76f8..887e058 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -334,10 +334,10 @@ namespace MLEM.Ui.Elements { public GenericCallback OnTouchExit; /// /// Event that is called when text input is made. - /// When an element uses this event, it should call on construction to ensure that a text input wrapper was set. + /// When an element uses this event, it should call on construction to ensure that the MLEM platform is initialized. /// /// Note that this event is called for every element, even if it is not selected. - /// Also note that if the active uses an on-screen keyboard, this event is never called. + /// Also note that if the active uses an on-screen keyboard, this event is never called. /// public TextInputCallback OnTextInput; /// diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 9f42051..ac2aba5 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -178,7 +178,7 @@ namespace MLEM.Ui.Elements { this.textScale = textScale; this.OnPressed += e => { foreach (var code in token.AppliedCodes.OfType()) - this.System?.LinkBehavior?.Invoke(code); + MlemPlatform.Current.OpenLinkOrFile(code.Match.Groups[1].Value); }; } diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs index 0c6565a..7605b41 100644 --- a/MLEM.Ui/Elements/TextField.cs +++ b/MLEM.Ui/Elements/TextField.cs @@ -17,7 +17,7 @@ namespace MLEM.Ui.Elements { /// /// A text field element for use inside of a . /// A text field is a selectable element that can be typed in, as well as copied and pasted from. - /// If an on-screen keyboard is required, then this text field will automatically open an on-screen keyboard using + /// If an on-screen keyboard is required, then this text field will automatically open an on-screen keyboard using . /// public class TextField : Element { @@ -141,10 +141,10 @@ namespace MLEM.Ui.Elements { if (font != null) this.Font.Set(font); - TextInputWrapper.EnsureExists(); + MlemPlatform.EnsureExists(); this.OnPressed += async e => { var title = this.MobileTitle ?? this.PlaceholderText; - var result = await TextInputWrapper.Current.OpenOnScreenKeyboard(title, this.MobileDescription, this.Text, false); + var result = await MlemPlatform.Current.OpenOnScreenKeyboard(title, this.MobileDescription, this.Text, false); if (result != null) this.SetText(result.Replace('\n', ' '), true); }; diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index 0ba7177..8439b72 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Text.RegularExpressions; using Microsoft.Xna.Framework; @@ -89,12 +88,6 @@ namespace MLEM.Ui { /// public TextFormatter TextFormatter; /// - /// The action that should be executed when a in a paragraph's is pressed. - /// The actual link stored in the link code is stored in its 's 1st group. - /// By default, the browser is opened with the given link's address. - /// - public Action LinkBehavior = l => Process.Start(new ProcessStartInfo(l.Match.Groups[1].Value) {UseShellExecute = true}); - /// /// The that this ui system is controlled by. /// The ui controls are also the place to change bindings for controller and keyboard input. /// @@ -190,8 +183,8 @@ namespace MLEM.Ui { }; } - if (TextInputWrapper.Current != null) - TextInputWrapper.Current.AddListener(game.Window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character))); + if (MlemPlatform.Current != null) + MlemPlatform.Current.AddTextInputListener(game.Window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character))); this.OnMousedElementChanged = e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e)); this.OnTouchedElementChanged = e => this.ApplyToAll(t => t.OnTouchedElementChanged?.Invoke(t, e)); this.OnSelectedElementChanged = e => this.ApplyToAll(t => t.OnSelectedElementChanged?.Invoke(t, e)); diff --git a/MLEM/MLEM.csproj b/MLEM/MLEM.csproj index e9bb8a7..a49fdc4 100644 --- a/MLEM/MLEM.csproj +++ b/MLEM/MLEM.csproj @@ -21,6 +21,6 @@ - + \ No newline at end of file diff --git a/MLEM/Misc/MlemPlatform.cs b/MLEM/Misc/MlemPlatform.cs new file mode 100644 index 0000000..846586a --- /dev/null +++ b/MLEM/Misc/MlemPlatform.cs @@ -0,0 +1,188 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; + +namespace MLEM.Misc { + /// + /// MlemPlatform is a wrapper around some of MonoGame's platform-dependent behavior to allow for MLEM to stay platform-independent. + /// See , and for information on the specific platforms. + /// The MLEM demos' main classes also make use of this functionality: and . + /// + public abstract class MlemPlatform { + + /// + /// The current MLEM platform + /// Set this value before starting your game if you want to use platform-dependent MLEM features. + /// + /// + public static MlemPlatform Current; + + /// + /// Opens the on-screen keyboard if one is required by the platform. + /// Note that, if no on-screen keyboard is required, a null string should be returned. + /// + /// Title of the dialog box. + /// Description of the dialog box. + /// Default text displayed in the input area. + /// If password mode is enabled, the characters entered are not displayed. + /// Text entered by the player. Null if back was used. + public abstract Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode); + + /// + /// Adds a text input listener to this platform, if supported. + /// The supplied listener will be called whenever a character is input. + /// + /// The game's window + /// The callback that should be called whenever a character is pressed + public abstract void AddTextInputListener(GameWindow window, TextInputCallback callback); + + /// + /// A method that should be executed to open a link in the browser or a file explorer + /// + public abstract void OpenLinkOrFile(string link); + + /// + /// Ensures that is set to a valid value by throwing an exception if is null. + /// + /// If is null + public static void EnsureExists() { + if (Current == null) + throw new InvalidOperationException("MlemPlatform was not initialized. For more information, see the MlemPlatform class or https://mlem.ellpeck.de/api/MLEM.Misc.MlemPlatform"); + } + + /// + /// A delegate method that can be used for + /// + /// The object that sent the event. The used in most cases. + /// The key that was pressed + /// The character that corresponds to that key + public delegate void TextInputCallback(object sender, Keys key, char character); + + /// + /// The MLEM DesktopGL platform. + /// This platform uses the built-in MonoGame TextInput event, which makes this listener work with any keyboard localization natively. + /// + /// + /// This platform is initialized as follows: + /// + /// new MlemPlatform.DesktopGl{TextInputEventArgs}((w, c) => w.TextInput += c) + /// + /// + /// + public class DesktopGl : MlemPlatform { + + private FieldInfo key; + private FieldInfo character; + private readonly Action> addListener; + + /// + /// Creates a new DesktopGL-based platform + /// See class documentation for more detailed information. + /// + /// The function that is used to add a text input listener + public DesktopGl(Action> addListener) { + this.addListener = addListener; + } + + /// + public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { + return Task.FromResult(null); + } + + /// + public override void AddTextInputListener(GameWindow window, TextInputCallback callback) { + this.addListener(window, (sender, args) => { + if (this.key == null) + this.key = args.GetType().GetField("Key"); + if (this.character == null) + this.character = args.GetType().GetField("Character"); + callback.Invoke(sender, (Keys) this.key.GetValue(args), (char) this.character.GetValue(args)); + }); + } + + /// + public override void OpenLinkOrFile(string link) { + Process.Start(new ProcessStartInfo(link) {UseShellExecute = true}); + } + + } + + /// + /// The MLEM platform for mobile platforms as well as consoles. + /// This platform opens an on-screen keyboard using the KeyboardInput class on mobile devices. + /// Additionally, it starts a new activity whenever is called. + /// + /// + /// This listener is initialized as follows in the game's Activity class: + /// + /// new MlemPlatform.Mobile(KeyboardInput.Show, l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l)))) + /// + /// + public class Mobile : MlemPlatform { + + private readonly OpenOnScreenKeyboardDelegate openOnScreenKeyboard; + private readonly Action openLink; + + /// + /// Creates a new mobile- and console-based platform. + /// See class documentation for more detailed information. + /// + /// The function that is used to display the on-screen keyboard + /// The action that is invoked to open the + public Mobile(OpenOnScreenKeyboardDelegate openOnScreenKeyboard, Action openLink) { + this.openOnScreenKeyboard = openOnScreenKeyboard; + this.openLink = openLink; + } + + /// + public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { + return this.openOnScreenKeyboard(title, description, defaultText, usePasswordMode); + } + + /// + public override void AddTextInputListener(GameWindow window, TextInputCallback callback) { + } + + /// + public override void OpenLinkOrFile(string link) { + this.openLink(link); + } + + /// + /// A delegate method used for + /// + /// Title of the dialog box. + /// Description of the dialog box. + /// Default text displayed in the input area. + /// If password mode is enabled, the characters entered are not displayed. + /// Text entered by the player. Null if back was used. + public delegate Task OpenOnScreenKeyboardDelegate(string title, string description, string defaultText, bool usePasswordMode); + + } + + /// + /// A MLEM platform implementation that does nothing. + /// This can be used if no platform-dependent code is required for the game. + /// + public class None : MlemPlatform { + + /// + public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { + return Task.FromResult(null); + } + + /// + public override void AddTextInputListener(GameWindow window, TextInputCallback callback) { + } + + /// + public override void OpenLinkOrFile(string link) { + } + + } + + } +} \ No newline at end of file diff --git a/MLEM/Misc/TextInputWrapper.cs b/MLEM/Misc/TextInputWrapper.cs deleted file mode 100644 index bb80f0c..0000000 --- a/MLEM/Misc/TextInputWrapper.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Input; -using MLEM.Input; - -namespace MLEM.Misc { - /// - /// A text input wrapper is a wrapper around MonoGame's built-in text input event. - /// Since said text input event does not exist on non-Desktop devices, we want to wrap it in a wrapper that is platform-independent for MLEM. - /// See subclasses of this wrapper or for more info. - /// - public abstract class TextInputWrapper { - - /// - /// The current text input wrapper. - /// Set this value before starting your game if you want to use text input wrapping. - /// - /// - public static TextInputWrapper Current; - - /// - /// Opens the on-screen keyboard for this text input wrapper. - /// Note that, if no on-screen keyboard is required, a null string should be returned. - /// - /// Title of the dialog box. - /// Description of the dialog box. - /// Default text displayed in the input area. - /// If password mode is enabled, the characters entered are not displayed. - /// Text entered by the player. Null if back was used. - public abstract Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode); - - /// - /// Adds a text input listener to this text input wrapper. - /// The supplied listener will be called whenever a character is input. - /// - /// The game's window - /// The callback that should be called whenever a character is pressed - public abstract void AddListener(GameWindow window, TextInputCallback callback); - - /// - /// Ensures that is set to a valid value by throwing an exception if is null. - /// - /// If is null - public static void EnsureExists() { - if (Current == null) - throw new InvalidOperationException("The TextInputWrapper was not initialized. For more information, see https://mlem.ellpeck.de/articles/ui.html#text-input"); - } - - /// - /// A delegate method that can be used for - /// - /// The object that sent the event. The used in most cases. - /// The key that was pressed - /// The character that corresponds to that key - public delegate void TextInputCallback(object sender, Keys key, char character); - - /// - /// A text input wrapper for DesktopGL devices. - /// This wrapper uses the built-in MonoGame TextInput event, which makes this listener work with any keyboard localization natively. - /// - /// - /// This listener is initialized as follows: - /// - /// new TextInputWrapper.DesktopGl{TextInputEventArgs}((w, c) => w.TextInput += c) - /// - /// - /// - public class DesktopGl : TextInputWrapper { - - private FieldInfo key; - private FieldInfo character; - private readonly Action> addListener; - - /// - /// Creates a new DesktopGL-based text input wrapper - /// - /// The function that is used to add a text input listener - public DesktopGl(Action> addListener) { - this.addListener = addListener; - } - - /// - public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { - return Task.FromResult(null); - } - - /// - public override void AddListener(GameWindow window, TextInputCallback callback) { - this.addListener(window, (sender, args) => { - if (this.key == null) - this.key = args.GetType().GetField("Key"); - if (this.character == null) - this.character = args.GetType().GetField("Character"); - callback.Invoke(sender, (Keys) this.key.GetValue(args), (char) this.character.GetValue(args)); - }); - } - - } - - /// - /// A text input wrapper for mobile platforms as well as consoles. - /// This text input wrapper opens an on-screen keyboard using the KeyboardInput class on mobile devices. - /// - /// - /// This listener is initialized as follows: - /// - /// new TextInputWrapper.Mobile(Microsoft.Xna.Framework.Input.KeyboardInput.Show) - /// - /// - public class Mobile : TextInputWrapper { - - private readonly OpenOnScreenKeyboardDelegate openOnScreenKeyboard; - - /// - /// Creates a new mobile- and console-based text input wrapper - /// - /// The function that is used to display the on-screen keyboard - public Mobile(OpenOnScreenKeyboardDelegate openOnScreenKeyboard) { - this.openOnScreenKeyboard = openOnScreenKeyboard; - } - - /// - public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { - return this.openOnScreenKeyboard(title, description, defaultText, usePasswordMode); - } - - /// - public override void AddListener(GameWindow window, TextInputCallback callback) { - } - - /// - /// A delegate method used for - /// - /// Title of the dialog box. - /// Description of the dialog box. - /// Default text displayed in the input area. - /// If password mode is enabled, the characters entered are not displayed. - /// Text entered by the player. Null if back was used. - public delegate Task OpenOnScreenKeyboardDelegate(string title, string description, string defaultText, bool usePasswordMode); - - } - - /// - /// A text input wrapper that does nothing. - /// This can be used if no text input is required for the game. - /// - public class None : TextInputWrapper { - - /// - public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { - return Task.FromResult(null); - } - - /// - public override void AddListener(GameWindow window, TextInputCallback callback) { - } - - } - - /// - /// A primitive text input wrapper that is locked to the American keyboard localization. - /// Only use this text input wrapper if is unavailable for some reason. - /// - /// Note that, when using this text input wrapper, its method has to be called periodically. - /// - public class Primitive : TextInputWrapper { - - private TextInputCallback callback; - - /// - /// Updates this text input wrapper by querying pressed keys and sending corresponding input events. - /// - /// The input handler to use for text input querying - public void Update(InputHandler handler) { - var pressed = handler.KeyboardState.GetPressedKeys().Except(handler.LastKeyboardState.GetPressedKeys()); - var shift = handler.IsModifierKeyDown(ModifierKey.Shift); - foreach (var key in pressed) { - var c = GetChar(key, shift); - if (c.HasValue) - this.callback?.Invoke(this, key, c.Value); - } - } - - /// - public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) { - return Task.FromResult(null); - } - - /// - public override void AddListener(GameWindow window, TextInputCallback callback) { - this.callback += callback; - } - - private static char? GetChar(Keys key, bool shift) { - if (key == Keys.A) return shift ? 'A' : 'a'; - if (key == Keys.B) return shift ? 'B' : 'b'; - if (key == Keys.C) return shift ? 'C' : 'c'; - if (key == Keys.D) return shift ? 'D' : 'd'; - if (key == Keys.E) return shift ? 'E' : 'e'; - if (key == Keys.F) return shift ? 'F' : 'f'; - if (key == Keys.G) return shift ? 'G' : 'g'; - if (key == Keys.H) return shift ? 'H' : 'h'; - if (key == Keys.I) return shift ? 'I' : 'i'; - if (key == Keys.J) return shift ? 'J' : 'j'; - if (key == Keys.K) return shift ? 'K' : 'k'; - if (key == Keys.L) return shift ? 'L' : 'l'; - if (key == Keys.M) return shift ? 'M' : 'm'; - if (key == Keys.N) return shift ? 'N' : 'n'; - if (key == Keys.O) return shift ? 'O' : 'o'; - if (key == Keys.P) return shift ? 'P' : 'p'; - if (key == Keys.Q) return shift ? 'Q' : 'q'; - if (key == Keys.R) return shift ? 'R' : 'r'; - if (key == Keys.S) return shift ? 'S' : 's'; - if (key == Keys.T) return shift ? 'T' : 't'; - if (key == Keys.U) return shift ? 'U' : 'u'; - if (key == Keys.V) return shift ? 'V' : 'v'; - if (key == Keys.W) return shift ? 'W' : 'w'; - if (key == Keys.X) return shift ? 'X' : 'x'; - if (key == Keys.Y) return shift ? 'Y' : 'y'; - if (key == Keys.Z) return shift ? 'Z' : 'z'; - if (key == Keys.D0 && !shift || key == Keys.NumPad0) return '0'; - if (key == Keys.D1 && !shift || key == Keys.NumPad1) return '1'; - if (key == Keys.D2 && !shift || key == Keys.NumPad2) return '2'; - if (key == Keys.D3 && !shift || key == Keys.NumPad3) return '3'; - if (key == Keys.D4 && !shift || key == Keys.NumPad4) return '4'; - if (key == Keys.D5 && !shift || key == Keys.NumPad5) return '5'; - if (key == Keys.D6 && !shift || key == Keys.NumPad6) return '6'; - if (key == Keys.D7 && !shift || key == Keys.NumPad7) return '7'; - if (key == Keys.D8 && !shift || key == Keys.NumPad8) return '8'; - if (key == Keys.D9 && !shift || key == Keys.NumPad9) return '9'; - if (key == Keys.D0 && shift) return ')'; - if (key == Keys.D1 && shift) return '!'; - if (key == Keys.D2 && shift) return '@'; - if (key == Keys.D3 && shift) return '#'; - if (key == Keys.D4 && shift) return '$'; - if (key == Keys.D5 && shift) return '%'; - if (key == Keys.D6 && shift) return '^'; - if (key == Keys.D7 && shift) return '&'; - if (key == Keys.D8 && shift) return '*'; - if (key == Keys.D9 && shift) return '('; - if (key == Keys.Space) return ' '; - if (key == Keys.Tab) return '\t'; - if (key == Keys.Add) return '+'; - if (key == Keys.Decimal) return '.'; - if (key == Keys.Divide) return '/'; - if (key == Keys.Multiply) return '*'; - if (key == Keys.OemBackslash) return '\\'; - if (key == Keys.OemComma && !shift) return ','; - if (key == Keys.OemComma && shift) return '<'; - if (key == Keys.OemOpenBrackets && !shift) return '['; - if (key == Keys.OemOpenBrackets && shift) return '{'; - if (key == Keys.OemCloseBrackets && !shift) return ']'; - if (key == Keys.OemCloseBrackets && shift) return '}'; - if (key == Keys.OemPeriod && !shift) return '.'; - if (key == Keys.OemPeriod && shift) return '>'; - if (key == Keys.OemPipe && !shift) return '\\'; - if (key == Keys.OemPipe && shift) return '|'; - if (key == Keys.OemPlus && !shift) return '='; - if (key == Keys.OemPlus && shift) return '+'; - if (key == Keys.OemMinus && !shift) return '-'; - if (key == Keys.OemMinus && shift) return '_'; - if (key == Keys.OemQuestion && !shift) return '/'; - if (key == Keys.OemQuestion && shift) return '?'; - if (key == Keys.OemQuotes && !shift) return '\''; - if (key == Keys.OemQuotes && shift) return '"'; - if (key == Keys.OemSemicolon && !shift) return ';'; - if (key == Keys.OemSemicolon && shift) return ':'; - if (key == Keys.OemTilde && !shift) return '`'; - if (key == Keys.OemTilde && shift) return '~'; - if (key == Keys.Subtract) return '-'; - return null; - } - - } - - } -} \ No newline at end of file diff --git a/Sandbox/Program.cs b/Sandbox/Program.cs index 646e1b3..70cd32a 100644 --- a/Sandbox/Program.cs +++ b/Sandbox/Program.cs @@ -5,7 +5,7 @@ namespace Sandbox { internal static class Program { private static void Main() { - TextInputWrapper.Current = new TextInputWrapper.DesktopGl((w, c) => w.TextInput += c); + MlemPlatform.Current = new MlemPlatform.DesktopGl((w, c) => w.TextInput += c); using var game = new GameImpl(); game.Run(); }