using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Foundation;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Input.Inking;
using Windows.UI.Input.Inking.Analysis;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
namespace JpInkRecognizer.ViewModel
{
public class BaseViewModel : Observable
{
public int CanvasTextStartIndex { get; set; } = 0;
///
/// inkAnalyzer
///
InkAnalyzer inkAnalyzer;
///
/// recoTimer
///
DispatcherTimer recoTimer;
private InkCanvas baseInkCanvas = null;
private UIElement showCanvasTextBox = null;
///
/// canvasTextStartIndex
///
public int canvasTextStartIndex = 0;
private int canvasTextLength = 0;
private bool canvasChangeFlag = false;
private bool textChangeFlag = false;
public string allowProcess = WinAppConstant.StrProcessDenied;
public Array WhiteListArray { get; set; }
public static SolidColorBrush GetSolidColorBush(string hex)
{
hex = hex.Replace("#", string.Empty);
bool existAlpha = hex.Length == 8;
if (!existAlpha && hex.Length != 6)
{
throw new ArgumentException();
}
int n = 0;
byte a;
if (existAlpha)
{
n = 2;
a = (byte)ConvertHexToByte(hex, 0);
}
else
{
a = 0xFF;
}
var r = (byte)ConvertHexToByte(hex, n);
var g = (byte)ConvertHexToByte(hex, n + 2);
var b = (byte)ConvertHexToByte(hex, n + 4);
return new SolidColorBrush(Color.FromArgb(a, r, g, b));
}
#region sample
public void InialInkCanvas(InkCanvas inkCanvas, UIElement textBox)
{
var type = textBox.GetType();
if (typeof(TextBox) == type)
{
showCanvasTextBox = textBox as TextBox;
}
else
{
showCanvasTextBox = textBox as RichEditBox;
}
this.baseInkCanvas = inkCanvas;
inkAnalyzer = new InkAnalyzer();
recoTimer = new DispatcherTimer();
recoTimer.Interval = TimeSpan.FromMilliseconds(300);
recoTimer.Tick += RecoTimer_Tick;
canvasTextStartIndex = 0;
this.canvasTextLength = 0;
this.baseInkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Touch | Windows.UI.Core.CoreInputDeviceTypes.Pen;
this.baseInkCanvas.InkPresenter.StrokeInput.StrokeStarted += StrokeInput_StrokeStarted;
var attr = new InkDrawingAttributes
{
Color = Colors.Red,
IgnorePressure = true,
PenTip = PenTipShape.Rectangle,
Size = new Size(4, 10),
PenTipTransform = Matrix3x2.CreateRotation((float)(70 * Math.PI / 180))
};
this.baseInkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attr);
}
///
/// RecoTimer_Tick
///
/// sender
/// object
private async void RecoTimer_Tick(object sender, object e)
{
recoTimer.Stop();
if (!inkAnalyzer.IsAnalyzing && WinAppConstant.StrProcessAllow.Equals(this.allowProcess))
{
this.allowProcess = WinAppConstant.StrProcessDenied;
InkAnalysisResult result = await inkAnalyzer.AnalyzeAsync();
if (result.Status == InkAnalysisStatus.Updated)
{
string tempRecognizedText = await GetRecognitionText();
string recognizedText = ToSBC(tempRecognizedText);
inkAnalyzer.ClearDataForAllStrokes();
await ShowTextBoxOfHandWrite(recognizedText.ToString());
}
this.allowProcess = WinAppConstant.StrProcessAllow;
}
else
{
recoTimer.Start();
}
}
///
/// Convert string from half character to full character
///
/// string to convert to full angle character
/// full angle character
private string ToSBC(string input)
{
char[] c = input.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
if (c[i] == 32)
{
c[i] = (char)12288;
continue;
}
//// a-z,1-0,A-Z
if (c[i] > 32 && c[i] < 127)
c[i] = (char)(c[i] + 65248);
}
return new string(c);
}
///
/// StrokeInput_StrokeStarted
///
///
///
private void StrokeInput_StrokeStarted(InkStrokeInput sender, Windows.UI.Core.PointerEventArgs args)
{
recoTimer?.Stop();
}
public async Task GetRecognitionText()
{
IReadOnlyList currentStrokes = this.baseInkCanvas.InkPresenter.StrokeContainer.GetStrokes();
if (currentStrokes.Count > 0)
{
InkRecognizerContainer inkRecognizerContainer = new InkRecognizerContainer();
if (inkRecognizerContainer != null)
{
var ink = inkRecognizerContainer.GetRecognizers();
foreach (var item in ink)
{
if ("Microsoft 日本語手書き認識エンジン".Equals(item.Name))
{
inkRecognizerContainer.SetDefaultRecognizer(item);
}
}
IReadOnlyList recognitionResults = await inkRecognizerContainer.RecognizeAsync(this.baseInkCanvas.InkPresenter.StrokeContainer, InkRecognitionTarget.All);
if (recognitionResults.Count > 0)
{
if (recognitionResults.Count > 0)
{
foreach (var result in recognitionResults)
{
IReadOnlyList candidates = result.GetTextCandidates();
return candidates[0];
}
}
}
}
}
return string.Empty;
}
public async Task ShowTextBoxOfHandWrite(string recognitionText)
{
var type = showCanvasTextBox.GetType();
if (type == typeof(TextBox))
{
TextBox _showCanvasTextBox = showCanvasTextBox as TextBox;
this.canvasTextStartIndex = _showCanvasTextBox.SelectionStart - this.canvasTextLength;
if (_showCanvasTextBox.SelectionLength <= 0)
{
string putString1 = _showCanvasTextBox.Text.Substring(0, this.canvasTextStartIndex);
string putString2 = _showCanvasTextBox.Text.Substring(this.canvasTextStartIndex + this.canvasTextLength);
_showCanvasTextBox.Text = putString1 + recognitionText + putString2;
_showCanvasTextBox.SelectionStart = this.canvasTextStartIndex + recognitionText.Length;
}
else
{
string putString1 = _showCanvasTextBox.Text.Substring(0, canvasTextStartIndex);
string putString2 = _showCanvasTextBox.Text.Substring(canvasTextStartIndex + _showCanvasTextBox.SelectionLength);
_showCanvasTextBox.Text = putString1 + recognitionText + putString2;
_showCanvasTextBox.SelectionStart = putString1.Length + recognitionText.Length;
}
this.canvasChangeFlag = true;
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.Background = new SolidColorBrush(Color.FromArgb(255, 140, 180, 228));
_showCanvasTextBox.SelectionLength = 0;
canvasTextLength = recognitionText.Length;
}
else
{
RichEditBox _showCanvasTextBox = showCanvasTextBox as RichEditBox;
canvasTextStartIndex = _showCanvasTextBox.Document.Selection.StartPosition;
string textStr = GetTextFromRichEditBox(_showCanvasTextBox);
int tempLength = canvasTextLength != 0 ? canvasTextLength : _showCanvasTextBox.Document.Selection.Length;
if (tempLength <= 0)
{
string putString1 = textStr.Substring(0, canvasTextStartIndex);
string putString2 = textStr.Substring(canvasTextStartIndex);
string allText = putString1 + recognitionText + putString2;
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, allText);
await ChangeTextColor(_showCanvasTextBox, allText, Colors.Red);
_showCanvasTextBox.Document.Selection.StartPosition = canvasTextStartIndex + recognitionText.Length;
}
else
{
string putString1 = textStr.Substring(0, canvasTextStartIndex - tempLength);
string putString2 = textStr.Substring(canvasTextStartIndex);
string allText = putString1 + recognitionText + putString2;
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, allText);
await ChangeTextColor(_showCanvasTextBox, allText, Colors.Red);
_showCanvasTextBox.Document.Selection.StartPosition = canvasTextStartIndex - tempLength + recognitionText.Length;
}
this.canvasChangeFlag = true;
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.Background = GetSolidColorBush("#F8B500");
canvasTextLength = recognitionText.Length;
}
}
///
/// Get Text from RichEditBox
///
/// the target richeditbox
/// the text of the richEditBox
private string GetTextFromRichEditBox(RichEditBox richEditBox)
{
string temp;
richEditBox.Document.GetText(Windows.UI.Text.TextGetOptions.None, out temp);
var range = richEditBox.Document.GetRange(0, temp.Length - 1);
string textStr;
range.GetText(Windows.UI.Text.TextGetOptions.None, out textStr);
return textStr;
}
public async Task ChangeTextColor(RichEditBox richEditBox, string s, Color color)
{
var temp = richEditBox.Document.GetRange(0, s.Length);
temp.CharacterFormat.BackgroundColor = Colors.Transparent;
ArrayList indexarray = await matchstring(s);
int tempPosition = richEditBox.Document.Selection.StartPosition;
foreach (int x in indexarray)
{
var tempRange = richEditBox.Document.GetRange(x, x + 1);
tempRange.CharacterFormat.BackgroundColor = Colors.Red;
richEditBox.Document.Selection.StartPosition = x + 1;
}
richEditBox.Document.Selection.StartPosition = tempPosition;
richEditBox.Document.Selection.EndPosition = tempPosition;
}
public async Task matchstring(string document)
{
if (WhiteListArray == null)
{
StorageFolder assetsStorageFolder = await Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFile file = await assetsStorageFolder.GetFileAsync("inputwhitelist.txt");
IList resultlist = await FileIO.ReadLinesAsync(file);
WhiteListArray = resultlist.ToArray();
}
char[] charlist = document.ToCharArray();
ArrayList indexlist = new ArrayList();
for (int i = 0; i < document.Length; i++)
{
int value = Convert.ToInt32(charlist[i]);
string hexoutput = String.Format("{0:X}", value);
int tmp = Array.IndexOf(WhiteListArray, hexoutput);
if (tmp == -1)
{
indexlist.Add(i);
}
}
await Task.CompletedTask;
return indexlist;
}
public void ClearCanvas()
{
// Clear Canvas
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
canvasTextLength = 0;
var type = showCanvasTextBox.GetType();
if (type == typeof(TextBox))
{
var _showCanvasTextBox = showCanvasTextBox as TextBox;
_showCanvasTextBox.Focus(FocusState.Programmatic);
}
else
{
var _showCanvasTextBox = showCanvasTextBox as RichEditBox;
_showCanvasTextBox.Focus(FocusState.Programmatic);
}
}
public void DeleteOneWord()
{
var type = showCanvasTextBox.GetType();
if (type == typeof(TextBox))
{
// Clear Canvas
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
canvasTextLength = 0;
var _showCanvasTextBox = showCanvasTextBox as TextBox;
if (_showCanvasTextBox.Text.Length > 0)
{
int selectPos = _showCanvasTextBox.SelectionStart;
if (_showCanvasTextBox.SelectionLength > 0)
{
string putString1 = _showCanvasTextBox.Text.Substring(0, selectPos);
string putString2 = _showCanvasTextBox.Text.Substring(selectPos + _showCanvasTextBox.SelectionLength);
_showCanvasTextBox.Text = putString1 + putString2;
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.SelectionStart = putString1.Length;
_showCanvasTextBox.SelectionLength = 0;
}
else
{
if (selectPos <= 0)
{
return;
}
string putString1 = _showCanvasTextBox.Text.Substring(0, selectPos - 1);
string putString2 = string.Empty;
putString2 += _showCanvasTextBox.Text.Substring(selectPos);
_showCanvasTextBox.Text = putString1 + putString2;
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.SelectionStart = selectPos - 1;
_showCanvasTextBox.SelectionLength = 0;
}
}
}
else
{
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
var _showCanvasTextBox = showCanvasTextBox as RichEditBox;
string textStr = GetTextFromRichEditBox(_showCanvasTextBox);
int tempLength = canvasTextLength != 0 ? canvasTextLength : _showCanvasTextBox.Document.Selection.Length;
canvasTextLength = 0;
if (textStr.Length > 0)
{
int selectPos = _showCanvasTextBox.Document.Selection.StartPosition;
if (selectPos <= 0)
{
return;
}
string putString1 = textStr.Substring(0, selectPos - 1);
string putString2 = string.Empty;
putString2 += textStr.Substring(selectPos);
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, putString1 + putString2);
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.Document.Selection.StartPosition = selectPos - 1;
}
}
}
public void DeleteAllWord()
{
// clear canvas and result
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
canvasTextLength = 0;
var type = showCanvasTextBox.GetType();
if (type == typeof(TextBox))
{
var _showCanvasTextBox = showCanvasTextBox as TextBox;
_showCanvasTextBox.Text = string.Empty;
}
else
{
var _showCanvasTextBox = showCanvasTextBox as RichEditBox;
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, string.Empty);
}
}
public void Blank()
{
var type = showCanvasTextBox.GetType();
if (type == typeof(TextBox))
{
var _showCanvasTextBox = showCanvasTextBox as TextBox;
//// clear canvas and result
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
canvasTextLength = 0;
int selectPos = _showCanvasTextBox.SelectionStart;
if (_showCanvasTextBox.SelectionLength > 0)
{
string putString1 = _showCanvasTextBox.Text.Substring(0, selectPos);
string putString2 = _showCanvasTextBox.Text.Substring(selectPos + _showCanvasTextBox.SelectionLength);
_showCanvasTextBox.Text = putString1 + " " + putString2;
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.SelectionStart = selectPos + 1;
_showCanvasTextBox.SelectionLength = 0;
}
else
{
_showCanvasTextBox.Text = _showCanvasTextBox.Text.Insert(selectPos, " ");
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.SelectionStart = selectPos + 1;
_showCanvasTextBox.SelectionLength = 0;
}
}
else
{
// clear canvas and result
this.baseInkCanvas.InkPresenter.StrokeContainer.Clear();
canvasTextLength = 0;
var _showCanvasTextBox = showCanvasTextBox as RichEditBox;
string textStr = GetTextFromRichEditBox(_showCanvasTextBox);
int selectPos = _showCanvasTextBox.Document.Selection.StartPosition;
int tempLength = canvasTextLength != 0 ? canvasTextLength : _showCanvasTextBox.Document.Selection.Length;
if (tempLength > 0)
{
string putString1 = textStr.Substring(0, selectPos);
string putString2 = textStr.Substring(selectPos + tempLength);
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, putString1 + " " + putString2);
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.Document.Selection.StartPosition = selectPos + 1;
}
else
{
_showCanvasTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, textStr.Insert(selectPos, " "));
_showCanvasTextBox.Focus(FocusState.Programmatic);
_showCanvasTextBox.Document.Selection.StartPosition = selectPos + 1;
}
}
}
public void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
if (this.allowProcess == WinAppConstant.StrProcessDenied)
{
return;
}
else
{
this.allowProcess = WinAppConstant.StrProcessDenied;
recoTimer?.Stop();
foreach (var stroke in args.Strokes)
{
var rect = stroke.BoundingRect;
inkAnalyzer.AddDataForStroke(stroke);
inkAnalyzer.SetStrokeDataKind(stroke.Id, InkAnalysisStrokeKind.Writing);
}
recoTimer?.Start();
this.allowProcess = WinAppConstant.StrProcessAllow;
}
}
public void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (!this.canvasChangeFlag && !this.textChangeFlag)
{
this.ClearCanvas();
}
else
{
this.canvasChangeFlag = false;
this.textChangeFlag = false;
}
}
public void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
this.textChangeFlag = true;
}
public void TextBox_OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
this.ClearCanvas();
}
private static uint ConvertHexToByte(string hex, int n)
{
return System.Convert.ToUInt32(hex.Substring(n, 2), 16);
}
#endregion
public void Tbx_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
e.Handled = true;
}
}
}