From 1ef56cadc5de741b3868965a21251f90e337e25a Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Mon, 8 Jan 2018 12:48:04 -0500 Subject: [PATCH 1/6] Initial project scaffold. --- src/.gitignore | 322 ++++++++++++++++++ src/BackEnd/OnScreenKeyboard.Logic/Class1.cs | 8 + .../OnScreenKeyboard.Logic.csproj | 7 + .../MapToKeyboardInput.csproj | 12 + src/FrontEnd/MapToKeyboardInput/Program.cs | 12 + src/OnScreenKeyboard.sln | 73 ++++ src/Tests/LogicTests/LogicTests.csproj | 19 ++ src/Tests/LogicTests/UnitTest1.cs | 13 + 8 files changed, 466 insertions(+) create mode 100644 src/.gitignore create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/Class1.cs create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/OnScreenKeyboard.Logic.csproj create mode 100644 src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj create mode 100644 src/FrontEnd/MapToKeyboardInput/Program.cs create mode 100644 src/OnScreenKeyboard.sln create mode 100644 src/Tests/LogicTests/LogicTests.csproj create mode 100644 src/Tests/LogicTests/UnitTest1.cs diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..9c455c3 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,322 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# TypeScript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog diff --git a/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs b/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs new file mode 100644 index 0000000..0371a20 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace OnScreenKeyboard.Logic +{ + public class Class1 + { + } +} diff --git a/src/BackEnd/OnScreenKeyboard.Logic/OnScreenKeyboard.Logic.csproj b/src/BackEnd/OnScreenKeyboard.Logic/OnScreenKeyboard.Logic.csproj new file mode 100644 index 0000000..9f5c4f4 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/OnScreenKeyboard.Logic.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj b/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj new file mode 100644 index 0000000..0a33d29 --- /dev/null +++ b/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj @@ -0,0 +1,12 @@ + + + + + + + + Exe + netcoreapp2.0 + + + diff --git a/src/FrontEnd/MapToKeyboardInput/Program.cs b/src/FrontEnd/MapToKeyboardInput/Program.cs new file mode 100644 index 0000000..3304a43 --- /dev/null +++ b/src/FrontEnd/MapToKeyboardInput/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace MapToKeyboardInput +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/src/OnScreenKeyboard.sln b/src/OnScreenKeyboard.sln new file mode 100644 index 0000000..3fe72cd --- /dev/null +++ b/src/OnScreenKeyboard.sln @@ -0,0 +1,73 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BackEnd", "BackEnd", "{987EA8CC-B8B2-4A04-97EB-F0F29DD096BC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnScreenKeyboard.Logic", "BackEnd\OnScreenKeyboard.Logic\OnScreenKeyboard.Logic.csproj", "{83812D7D-871C-4786-B9F2-91DB315721E0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FrontEnd", "FrontEnd", "{9C3F1701-A97C-4BDA-8DCA-354E391F635A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapToKeyboardInput", "FrontEnd\MapToKeyboardInput\MapToKeyboardInput.csproj", "{7565402E-00FD-468B-9DD1-4AFE8101DECF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{798031D8-B876-4BDA-B7C1-A4760B18CC20}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogicTests", "Tests\LogicTests\LogicTests.csproj", "{64B5B8B4-E012-4918-AFEE-5BA484C9920F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.ActiveCfg = Debug|x64 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.Build.0 = Debug|x64 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.ActiveCfg = Debug|x86 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.Build.0 = Debug|x86 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|Any CPU.Build.0 = Release|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.ActiveCfg = Release|x64 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.Build.0 = Release|x64 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.ActiveCfg = Release|x86 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.Build.0 = Release|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.ActiveCfg = Debug|x64 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.Build.0 = Debug|x64 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.ActiveCfg = Debug|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.Build.0 = Debug|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|Any CPU.Build.0 = Release|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.ActiveCfg = Release|x64 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.Build.0 = Release|x64 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.ActiveCfg = Release|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.Build.0 = Release|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.ActiveCfg = Debug|x64 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.Build.0 = Debug|x64 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.ActiveCfg = Debug|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.Build.0 = Debug|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|Any CPU.Build.0 = Release|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.ActiveCfg = Release|x64 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.Build.0 = Release|x64 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.ActiveCfg = Release|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {83812D7D-871C-4786-B9F2-91DB315721E0} = {987EA8CC-B8B2-4A04-97EB-F0F29DD096BC} + {7565402E-00FD-468B-9DD1-4AFE8101DECF} = {9C3F1701-A97C-4BDA-8DCA-354E391F635A} + {64B5B8B4-E012-4918-AFEE-5BA484C9920F} = {798031D8-B876-4BDA-B7C1-A4760B18CC20} + EndGlobalSection +EndGlobal diff --git a/src/Tests/LogicTests/LogicTests.csproj b/src/Tests/LogicTests/LogicTests.csproj new file mode 100644 index 0000000..a444bd2 --- /dev/null +++ b/src/Tests/LogicTests/LogicTests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.0 + + false + + + + + + + + + + + + + diff --git a/src/Tests/LogicTests/UnitTest1.cs b/src/Tests/LogicTests/UnitTest1.cs new file mode 100644 index 0000000..f9d02ae --- /dev/null +++ b/src/Tests/LogicTests/UnitTest1.cs @@ -0,0 +1,13 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace LogicTests +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + } + } +} From ae32dca37a570141cdaa4f64747cc48e11db14fa Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Mon, 8 Jan 2018 17:50:03 -0500 Subject: [PATCH 2/6] Core logic implemented. --- src/BackEnd/OnScreenKeyboard.Logic/Class1.cs | 8 -- .../OnScreenKeyboard.Logic/IKeyboardLayout.cs | 11 ++ .../OnScreenKeyboard.Logic/InputProcessor.cs | 104 ++++++++++++++++++ .../OnScreenKeyboard.Logic/KeyLocation.cs | 18 +++ .../SixBySixKeyboardLayout.cs | 26 +++++ src/OnScreenKeyboard.sln | 66 +++++------ src/Tests/LogicTests/UnitTest1.cs | 7 ++ 7 files changed, 200 insertions(+), 40 deletions(-) delete mode 100644 src/BackEnd/OnScreenKeyboard.Logic/Class1.cs create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/IKeyboardLayout.cs create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/KeyLocation.cs create mode 100644 src/BackEnd/OnScreenKeyboard.Logic/SixBySixKeyboardLayout.cs diff --git a/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs b/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs deleted file mode 100644 index 0371a20..0000000 --- a/src/BackEnd/OnScreenKeyboard.Logic/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace OnScreenKeyboard.Logic -{ - public class Class1 - { - } -} diff --git a/src/BackEnd/OnScreenKeyboard.Logic/IKeyboardLayout.cs b/src/BackEnd/OnScreenKeyboard.Logic/IKeyboardLayout.cs new file mode 100644 index 0000000..2f5eb43 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/IKeyboardLayout.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OnScreenKeyboard.Logic +{ + public interface IKeyboardLayout + { + KeyLocation? GetKeyLocation(char key); + } +} diff --git a/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs b/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs new file mode 100644 index 0000000..8f5b362 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs @@ -0,0 +1,104 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; + +namespace OnScreenKeyboard.Logic +{ + public class InputProcessor + { + public InputProcessor(IKeyboardLayout keyboardLayout) + { + _keyboardLayout = keyboardLayout ?? throw new ArgumentNullException(nameof(keyboardLayout)); + } + + private IKeyboardLayout _keyboardLayout; + + /// + /// Convert all characters to upper case, all punctuation to spaces and remove any repeated + /// spaces. + /// + public string ScrubInput(string input) + { + if (input == null) + return null; + + bool lastCharWasSpace = false; + var sb = new StringBuilder(); + + foreach(char c in input.Trim().ToUpper()) + { + char cc = char.IsPunctuation(c) ? ' ' : c; + if (cc == ' ') + { + if (lastCharWasSpace) continue; + else lastCharWasSpace = true; + } + else + lastCharWasSpace = false; + sb.Append(cc); + } + + return sb.ToString().Trim(); + } + + /// + /// Convert an input string into a sequence of key locations seperated by spaces. + /// + public List> ToKeyLocationSequences(string input) + => ScrubInput(input)?.Split(' ') + ?.Select(word => + word.Select(c => _keyboardLayout.GetKeyLocation(c)) + .Where(kl => kl != null) + .Cast() + .ToList()) + ?.ToList(); + + + /// + /// Convert an input string into fin + /// + /// + /// + public string ToCursorInstructions(string input) + { + var keySequences = ToKeyLocationSequences(input); + if (keySequences == null) + return null; + + var currentLocation = new KeyLocation { Row = 0, Column = 0 }; + return + string.Join("S,", + keySequences.Select(seq => string.Join(",", + seq.Select( + keyLoc => + { + var result = ToRelativeCursorInstructions(currentLocation, keyLoc); + currentLocation = keyLoc; + return result; + })))); + + } + + private string ToRelativeCursorInstructions(KeyLocation currentLocation, KeyLocation targetLocation) + { + var diff = targetLocation - currentLocation; + var sb = new StringBuilder(); + + for (int i = 0; i < diff.Column; i++) + sb.Append("R,"); + for (int i = 0; i > diff.Column; i--) + sb.Append("L,"); + for (int i = 0; i < diff.Row; i++) + sb.Append("D,"); + for (int i = 0; i > diff.Row; i--) + sb.Append("U,"); + + sb.Append("#"); + + + return sb.ToString(); + } + + } +} diff --git a/src/BackEnd/OnScreenKeyboard.Logic/KeyLocation.cs b/src/BackEnd/OnScreenKeyboard.Logic/KeyLocation.cs new file mode 100644 index 0000000..f958f71 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/KeyLocation.cs @@ -0,0 +1,18 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; + +namespace OnScreenKeyboard.Logic +{ + public struct KeyLocation + { + public int Row; + public int Column; + + public static KeyLocation operator +(KeyLocation a, KeyLocation b) + => new KeyLocation { Row = a.Row + b.Row, Column = a.Column + b.Column }; + public static KeyLocation operator -(KeyLocation a, KeyLocation b) + => new KeyLocation { Row = a.Row - b.Row, Column = a.Column - b.Column }; + } +} diff --git a/src/BackEnd/OnScreenKeyboard.Logic/SixBySixKeyboardLayout.cs b/src/BackEnd/OnScreenKeyboard.Logic/SixBySixKeyboardLayout.cs new file mode 100644 index 0000000..b405431 --- /dev/null +++ b/src/BackEnd/OnScreenKeyboard.Logic/SixBySixKeyboardLayout.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OnScreenKeyboard.Logic +{ + public class SixBySixKeyboardLayout : IKeyboardLayout + { + private static char[] _keys = + { + 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '0', + }; + + public KeyLocation? GetKeyLocation(char key) + { + int keyIndex = Array.IndexOf(_keys, char.ToUpper(key)); + return keyIndex < 0 ? (KeyLocation?)null + : new KeyLocation { Row = keyIndex / 6, Column = keyIndex % 6 }; + } + } +} diff --git a/src/OnScreenKeyboard.sln b/src/OnScreenKeyboard.sln index 3fe72cd..75d991d 100644 --- a/src/OnScreenKeyboard.sln +++ b/src/OnScreenKeyboard.sln @@ -1,19 +1,18 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +VisualStudioVersion = 15.0.27004.2005 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BackEnd", "BackEnd", "{987EA8CC-B8B2-4A04-97EB-F0F29DD096BC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnScreenKeyboard.Logic", "BackEnd\OnScreenKeyboard.Logic\OnScreenKeyboard.Logic.csproj", "{83812D7D-871C-4786-B9F2-91DB315721E0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OnScreenKeyboard.Logic", "BackEnd\OnScreenKeyboard.Logic\OnScreenKeyboard.Logic.csproj", "{83812D7D-871C-4786-B9F2-91DB315721E0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FrontEnd", "FrontEnd", "{9C3F1701-A97C-4BDA-8DCA-354E391F635A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapToKeyboardInput", "FrontEnd\MapToKeyboardInput\MapToKeyboardInput.csproj", "{7565402E-00FD-468B-9DD1-4AFE8101DECF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MapToKeyboardInput", "FrontEnd\MapToKeyboardInput\MapToKeyboardInput.csproj", "{7565402E-00FD-468B-9DD1-4AFE8101DECF}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{798031D8-B876-4BDA-B7C1-A4760B18CC20}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogicTests", "Tests\LogicTests\LogicTests.csproj", "{64B5B8B4-E012-4918-AFEE-5BA484C9920F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LogicTests", "Tests\LogicTests\LogicTests.csproj", "{64B5B8B4-E012-4918-AFEE-5BA484C9920F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -24,50 +23,53 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.ActiveCfg = Debug|x64 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.Build.0 = Debug|x64 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.ActiveCfg = Debug|x86 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.Build.0 = Debug|x86 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.ActiveCfg = Debug|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x64.Build.0 = Debug|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Debug|x86.Build.0 = Debug|Any CPU {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|Any CPU.Build.0 = Release|Any CPU - {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.ActiveCfg = Release|x64 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.Build.0 = Release|x64 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.ActiveCfg = Release|x86 - {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.Build.0 = Release|x86 + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.ActiveCfg = Release|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x64.Build.0 = Release|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.ActiveCfg = Release|Any CPU + {83812D7D-871C-4786-B9F2-91DB315721E0}.Release|x86.Build.0 = Release|Any CPU {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.ActiveCfg = Debug|x64 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.Build.0 = Debug|x64 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.ActiveCfg = Debug|x86 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.Build.0 = Debug|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.ActiveCfg = Debug|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x64.Build.0 = Debug|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.ActiveCfg = Debug|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Debug|x86.Build.0 = Debug|Any CPU {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|Any CPU.ActiveCfg = Release|Any CPU {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|Any CPU.Build.0 = Release|Any CPU - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.ActiveCfg = Release|x64 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.Build.0 = Release|x64 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.ActiveCfg = Release|x86 - {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.Build.0 = Release|x86 + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.ActiveCfg = Release|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x64.Build.0 = Release|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.ActiveCfg = Release|Any CPU + {7565402E-00FD-468B-9DD1-4AFE8101DECF}.Release|x86.Build.0 = Release|Any CPU {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.ActiveCfg = Debug|x64 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.Build.0 = Debug|x64 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.ActiveCfg = Debug|x86 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.Build.0 = Debug|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.ActiveCfg = Debug|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x64.Build.0 = Debug|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.ActiveCfg = Debug|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Debug|x86.Build.0 = Debug|Any CPU {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|Any CPU.ActiveCfg = Release|Any CPU {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|Any CPU.Build.0 = Release|Any CPU - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.ActiveCfg = Release|x64 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.Build.0 = Release|x64 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.ActiveCfg = Release|x86 - {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.Build.0 = Release|x86 + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.ActiveCfg = Release|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x64.Build.0 = Release|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.ActiveCfg = Release|Any CPU + {64B5B8B4-E012-4918-AFEE-5BA484C9920F}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {83812D7D-871C-4786-B9F2-91DB315721E0} = {987EA8CC-B8B2-4A04-97EB-F0F29DD096BC} {7565402E-00FD-468B-9DD1-4AFE8101DECF} = {9C3F1701-A97C-4BDA-8DCA-354E391F635A} {64B5B8B4-E012-4918-AFEE-5BA484C9920F} = {798031D8-B876-4BDA-B7C1-A4760B18CC20} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {793D06F3-A316-4065-8A4B-85AEA2E31382} + EndGlobalSection EndGlobal diff --git a/src/Tests/LogicTests/UnitTest1.cs b/src/Tests/LogicTests/UnitTest1.cs index f9d02ae..8396afd 100644 --- a/src/Tests/LogicTests/UnitTest1.cs +++ b/src/Tests/LogicTests/UnitTest1.cs @@ -1,4 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using OnScreenKeyboard.Logic; namespace LogicTests { @@ -8,6 +9,12 @@ public class UnitTest1 [TestMethod] public void TestMethod1() { + var inputProcessor = new InputProcessor(new SixBySixKeyboardLayout()); + + string input = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + Assert.AreEqual( + "#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#", + inputProcessor.ToCursorInstructions(input)); } } } From 002200d913053f8705f7d7ce2011a424c544f1b9 Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Mon, 8 Jan 2018 18:33:34 -0500 Subject: [PATCH 3/6] Added tests. --- .../OnScreenKeyboard.Logic/InputProcessor.cs | 36 +++++++-------- src/Tests/LogicTests/InputProcessorTests.cs | 45 +++++++++++++++++++ src/Tests/LogicTests/UnitTest1.cs | 20 --------- 3 files changed, 63 insertions(+), 38 deletions(-) create mode 100644 src/Tests/LogicTests/InputProcessorTests.cs delete mode 100644 src/Tests/LogicTests/UnitTest1.cs diff --git a/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs b/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs index 8f5b362..2c4dbd1 100644 --- a/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs +++ b/src/BackEnd/OnScreenKeyboard.Logic/InputProcessor.cs @@ -28,7 +28,7 @@ public string ScrubInput(string input) foreach(char c in input.Trim().ToUpper()) { - char cc = char.IsPunctuation(c) ? ' ' : c; + char cc = (char.IsPunctuation(c) || char.IsSymbol(c)) ? ' ' : c; if (cc == ' ') { if (lastCharWasSpace) continue; @@ -43,23 +43,8 @@ public string ScrubInput(string input) } /// - /// Convert an input string into a sequence of key locations seperated by spaces. + /// Convert an input string into instructions to move the cursor around the on screen keyboard. /// - public List> ToKeyLocationSequences(string input) - => ScrubInput(input)?.Split(' ') - ?.Select(word => - word.Select(c => _keyboardLayout.GetKeyLocation(c)) - .Where(kl => kl != null) - .Cast() - .ToList()) - ?.ToList(); - - - /// - /// Convert an input string into fin - /// - /// - /// public string ToCursorInstructions(string input) { var keySequences = ToKeyLocationSequences(input); @@ -68,7 +53,7 @@ public string ToCursorInstructions(string input) var currentLocation = new KeyLocation { Row = 0, Column = 0 }; return - string.Join("S,", + string.Join(",S,", keySequences.Select(seq => string.Join(",", seq.Select( keyLoc => @@ -80,6 +65,21 @@ public string ToCursorInstructions(string input) } + /// + /// Convert an input string into a sequence of key locations seperated by spaces. + /// + private List> ToKeyLocationSequences(string input) + => ScrubInput(input)?.Split(' ') + ?.Select(word => + word.Select(c => _keyboardLayout.GetKeyLocation(c)) + .Where(kl => kl != null) + .Cast() + .ToList()) + ?.ToList(); + + /// + /// Generate the instructions to move from one key to another. + /// private string ToRelativeCursorInstructions(KeyLocation currentLocation, KeyLocation targetLocation) { var diff = targetLocation - currentLocation; diff --git a/src/Tests/LogicTests/InputProcessorTests.cs b/src/Tests/LogicTests/InputProcessorTests.cs new file mode 100644 index 0000000..a1cdb6e --- /dev/null +++ b/src/Tests/LogicTests/InputProcessorTests.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OnScreenKeyboard.Logic; + +namespace LogicTests +{ + [TestClass] + public class InputProcessorTests + { + [TestInitialize] + public void Init() + { + _processor = new InputProcessor(new SixBySixKeyboardLayout()); + } + + InputProcessor _processor; + + [TestMethod] + public void ScrubInput() + { + Assert.AreEqual( + "TEST TEST 123", + _processor.ScrubInput("Test \"Test\" 123 :';,.<>/?\\")); + } + + [TestMethod] + public void ToCursorInstructions() + { + + Assert.AreEqual( + "#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#", + _processor.ToCursorInstructions("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")); + + Assert.AreEqual( + "R,D,D,D,#,R,R,R,U,U,U,#,L,L,L,L,D,D,D,#,R,#,S,#,R,R,R,U,U,U,#,L,L,L,L,D,D,D,#,R,#", + _processor.ToCursorInstructions("TEST TEST")); + + Assert.AreEqual( + "R,D,D,D,#,R,R,R,U,U,U,#,L,L,L,L,D,D,D,#,R,#,S,#,R,R,R,U,U,U,#,L,L,L,L,D,D,D,#,R,#,S,R,D,#,R,#,R,#", + _processor.ToCursorInstructions("Test \"Test\" 123 :';,.<>/?\\")); + } + } +} diff --git a/src/Tests/LogicTests/UnitTest1.cs b/src/Tests/LogicTests/UnitTest1.cs deleted file mode 100644 index 8396afd..0000000 --- a/src/Tests/LogicTests/UnitTest1.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using OnScreenKeyboard.Logic; - -namespace LogicTests -{ - [TestClass] - public class UnitTest1 - { - [TestMethod] - public void TestMethod1() - { - var inputProcessor = new InputProcessor(new SixBySixKeyboardLayout()); - - string input = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - Assert.AreEqual( - "#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#,L,L,L,L,L,D,#,R,#,R,#,R,#,R,#,R,#", - inputProcessor.ToCursorInstructions(input)); - } - } -} From ca5bc8daa52f1f3063cc36baef1a69d7b1c5e166 Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Tue, 9 Jan 2018 10:10:07 -0500 Subject: [PATCH 4/6] Added command line tool to run the translation. --- .../MapToKeyboardInput.csproj | 2 ++ src/FrontEnd/MapToKeyboardInput/Program.cs | 27 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj b/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj index 0a33d29..f9967f7 100644 --- a/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj +++ b/src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj @@ -7,6 +7,8 @@ Exe netcoreapp2.0 + win10-x64 + 7.1 diff --git a/src/FrontEnd/MapToKeyboardInput/Program.cs b/src/FrontEnd/MapToKeyboardInput/Program.cs index 3304a43..ce2ae1c 100644 --- a/src/FrontEnd/MapToKeyboardInput/Program.cs +++ b/src/FrontEnd/MapToKeyboardInput/Program.cs @@ -1,12 +1,33 @@ using System; +using System.IO; +using System.Threading.Tasks; namespace MapToKeyboardInput { - class Program + public class Program { - static void Main(string[] args) + public static async Task Main(string[] args) { - Console.WriteLine("Hello World!"); + using (var stdin = Console.OpenStandardInput()) + using (var stdout = Console.OpenStandardOutput()) + await ProcessAsync(stdin, stdout); + } + + /// + /// Read lines from the input stream and write the cursor instructions to the output stream. + /// + private static async Task ProcessAsync(Stream stdin, Stream stdout) + { + var processor = new OnScreenKeyboard.Logic.InputProcessor(new OnScreenKeyboard.Logic.SixBySixKeyboardLayout()); + + using (var reader = new StreamReader(stdin)) + using (var writer = new StreamWriter(stdout)) + { + string input = null; + while ((input = await reader.ReadLineAsync()) != null) + writer.WriteLine(processor.ToCursorInstructions(input)); + } + } } } From 29d85a4ce22c870fdffb1a81792cf6cc9549cfd7 Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Tue, 9 Jan 2018 10:11:00 -0500 Subject: [PATCH 5/6] Added test data and scripts to build the binaries and run the test data. --- PublishBin.cmd | 2 ++ RunTest.cmd | 17 +++++++++++++++++ data/TestData.txt | 3 +++ 3 files changed, 22 insertions(+) create mode 100644 PublishBin.cmd create mode 100644 RunTest.cmd create mode 100644 data/TestData.txt diff --git a/PublishBin.cmd b/PublishBin.cmd new file mode 100644 index 0000000..0e57229 --- /dev/null +++ b/PublishBin.cmd @@ -0,0 +1,2 @@ +IF NOT EXIST bin\ mkdir bin +dotnet publish src/FrontEnd/MapToKeyboardInput/MapToKeyboardInput.csproj -c Release -f netcoreapp2.0 -r win10-x64 -o ../../../bin/ diff --git a/RunTest.cmd b/RunTest.cmd new file mode 100644 index 0000000..0ce2bb3 --- /dev/null +++ b/RunTest.cmd @@ -0,0 +1,17 @@ +@echo OFF +echo. +IF NOT EXIST bin\ ( + echo Please run PublishBin.cmd before running the test. +) else ( + echo Input: + echo. + cat data\TestData.txt + echo. + echo. + echo Output: + echo. + cat data\TestData.txt | bin\MapToKeyboardInput.exe +) +echo. + + diff --git a/data/TestData.txt b/data/TestData.txt new file mode 100644 index 0000000..802aab4 --- /dev/null +++ b/data/TestData.txt @@ -0,0 +1,3 @@ +ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 +TEST TEST +Test \"Test\" :';,.<>/?\\ \ No newline at end of file From c7acdd69cc4692563150627be3fd9a6fa4c8861e Mon Sep 17 00:00:00 2001 From: lukeatron <1340234+lukeatron@users.noreply.github.com> Date: Tue, 9 Jan 2018 10:45:43 -0500 Subject: [PATCH 6/6] Updated README.md. --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 2c16e5c..ae5161e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,23 @@ On Screen Keyboard ================== +Quick Start +- +This solution is built on dot net core 2.0. It requires the dot net core 2.0 SDK to be installed to build. This is installed automatically with the latest version of Visual Studio 2017. + +1. Run `PublishBin.cmd` to build the solution to the `bin` folder. +2. Run `RunTest.cmd` to pipe the data in the file `data\TestData.txt` through the `MapToKeyboardInput` utility and write the output to `stdout`. + +The Solution +- +`MapToKeyboardInput.exe` is a utility that reads lines from `stdin` and translates the text to cursor instructions, which are written to `stdout`. This allows for easy use in scripts, the most likely use for a utility like this. To read the test data and write it to a file called `output.txt` the command would be: + + cat data\TestData.txt | bin\MapToKeyboardInput.exe > output.txt + +In the solution, the core logic is broken out into it's own assembly that could be referenced by other projects that need this functionality. The MapToKeyboardInput project is a thin command line interface to the OnScreenKeyboard.Logic API. The solution also contains some simple tests of the API. + +--- + The Problem ----------- On screen keyboards are the bane of DVR users. To help alleviate the pain, one local company is asking you to implement part of a voice to text search for their DVR by developing an algorithm to script the on screen keyboard.