#endif
bool nowCaretMove = false;
bool nowCompstion = false;
+ bool requestSizeChange = false;
Document _Document;
DispatcherTimer timer = new DispatcherTimer();
+ const int Interval = 32;
+ const int IntervalWhenLostFocus = 160;
+
/// <summary>
/// コンストラクター
/// </summary>
this.Document = new Document();
- this.View = new EditView(this.Document, this.Render, new Padding(5, Gripper.HitAreaWidth, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth));
+ this.View = new EditView(this.Document, this.Render, new Padding(5, 5, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth));
this.View.SrcChanged += View_SrcChanged;
this.View.InsertMode = this.InsertMode;
this.Document.DrawLineNumber = this.DrawLineNumber;
this.gestureRecongnizer.ManipulationUpdated += gestureRecongnizer_ManipulationUpdated;
this.gestureRecongnizer.ManipulationCompleted += gestureRecongnizer_ManipulationCompleted;
- this.timer.Interval = new TimeSpan(0, 0, 0, 0, 16);
+ this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
this.timer.Tick += this.timer_Tick;
this.timer.Start();
+ this.GettingFocus += FooTextBox_GettingFocus;
+ this.LosingFocus += FooTextBox_LosingFocus;
+
this.SizeChanged += FooTextBox_SizeChanged;
this.Loaded += FooTextBox_Loaded;
var dataPackageView = Clipboard.GetContent();
if (dataPackageView.Contains(StandardDataFormats.Text))
{
- this._Controller.SelectedText = await dataPackageView.GetTextAsync();
+ try
+ {
+ this._Controller.SelectedText = await dataPackageView.GetTextAsync();
+ }catch(Exception e)
+ {
+ System.Diagnostics.Debug.WriteLine("past error:" + e.Message);
+ }
}
}
/// <summary>
/// 再描写する
/// </summary>
- public void Refresh()
+ public void Refresh(bool immidately=true)
{
- this.Document.RequestRedraw();
+ if(immidately)
+ this.Refresh(this.View.PageBound);
+ else
+ this.Document.RequestRedraw();
}
/// <summary>
if (this.verticalScrollBar != null)
this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
this.IsEnabled = true;
- this.Refresh(this.View.PageBound);
+ this.Refresh(false);
}
}
}
}
- /// <inheritdoc/>
- protected override async void OnGotFocus(RoutedEventArgs e)
+ private void FooTextBox_LosingFocus(UIElement sender, LosingFocusEventArgs args)
{
- base.OnGotFocus(e);
+ this.RemoveTextContext();
+
+ if (this.textServiceManager != null)
+ {
+ this.textServiceManager.InputLanguageChanged -= TextServiceManager_InputLanguageChanged;
+ this.textServiceManager = null;
+ }
- if(this.textServiceManager == null)
+ System.Diagnostics.Debug.WriteLine("losing focus");
+ }
+
+ private async void FooTextBox_GettingFocus(UIElement sender, GettingFocusEventArgs args)
+ {
+ System.Diagnostics.Debug.WriteLine("getting focus");
+ if (this.textServiceManager == null)
{
await Task.Delay(500);
this.textServiceManager = CoreTextServicesManager.GetForCurrentView();
}
this.CreateTextContext();
+ }
+
+ /// <inheritdoc/>
+ protected override void OnGotFocus(RoutedEventArgs e)
+ {
+ base.OnGotFocus(e);
+
+ System.Diagnostics.Debug.WriteLine("got focus");
this.View.IsFocused = true;
- this.timer.Start();
- this.Refresh();
+ this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
+ this.Refresh(false);
}
private void TextServiceManager_InputLanguageChanged(CoreTextServicesManager sender, object args)
{
System.Diagnostics.Debug.WriteLine("input language changed input script:"+ this.textServiceManager.InputLanguage.Script);
- this.RemoveTextContext();
- this.CreateTextContext();
}
- /// <inheritdoc/>
+ /// <inheritdoc/>
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
- this.RemoveTextContext();
-
+ System.Diagnostics.Debug.WriteLine("lost focus");
+
this.View.IsFocused = false;
- this.Refresh(this.View.PageBound);
- this.timer.Stop();
+ this.Refresh(false);
+ this.timer.Interval = new TimeSpan(0, 0, 0, 0, IntervalWhenLostFocus);
}
private void CreateTextContext()
if(this.textServiceManager != null)
{
this.textEditContext = this.textServiceManager.CreateEditContext();
+ this.textEditContext.InputScope = CoreTextInputScope.Text;
this.textEditContext.CompositionStarted += TextEditContext_CompositionStarted;
this.textEditContext.CompositionCompleted += TextEditContext_CompositionCompleted;
this.textEditContext.LayoutRequested += TextEditContext_LayoutRequested;
{
if(this.textEditContext != null)
{
+ this.textEditContext.NotifyFocusLeave();
this.textEditContext.CompositionStarted -= TextEditContext_CompositionStarted;
this.textEditContext.CompositionCompleted -= TextEditContext_CompositionCompleted;
this.textEditContext.LayoutRequested -= TextEditContext_LayoutRequested;
this.textEditContext.FormatUpdating -= TextEditContext_FormatUpdating;
this.textEditContext.FocusRemoved -= TextEditContext_FocusRemoved;
this.textEditContext.NotifyFocusLeaveCompleted -= TextEditContext_NotifyFocusLeaveCompleted;
- this.textEditContext.NotifyFocusLeave();
this.textEditContext = null;
}
}
/// <inheritdoc/>
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
+ System.Diagnostics.Debug.WriteLine("pointer pressed");
this.CapturePointer(e.Pointer);
this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this));
e.Handled = true;
/// <inheritdoc/>
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
- this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
+ System.Diagnostics.Debug.WriteLine("pointer moved");
+ try
+ {
+ this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
+ }catch(System.Runtime.InteropServices.COMException ex)
+ {
+ //ピンチズームでこの例外が発生するが、回避できない
+ System.Diagnostics.Debug.WriteLine("expection:" + ex);
+ }
e.Handled = true;
if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
/// <inheritdoc/>
protected override void OnPointerReleased(PointerRoutedEventArgs e)
{
+ System.Diagnostics.Debug.WriteLine("pointer released");
this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this));
e.Handled = true;
}
/// <inheritdoc/>
protected override void OnPointerCanceled(PointerRoutedEventArgs e)
{
+ System.Diagnostics.Debug.WriteLine("pointer canceled");
this.gestureRecongnizer.CompleteGesture();
e.Handled = true;
}
/// <inheritdoc/>
protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
{
+ System.Diagnostics.Debug.WriteLine("pointer wheelchanged");
bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
Windows.System.VirtualKeyModifiers.Shift;
bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
args.Request.LayoutBounds.TextBounds = new Rect(
screenStartPos.X,
screenStartPos.Y,
- screenEndPos.X - screenStartPos.X,
+ Math.Max(0,screenEndPos.X - screenStartPos.X), //折り返されている場合、負になることがある
screenEndPos.Y - screenStartPos.Y);
}
this._Controller.RectSelection = true;
}));
}
- await ContextMenu.ShowAsync(e.Position);
+ var windowStartPos = Util.GetPointInWindow(e.Position, this);
+ await ContextMenu.ShowAsync(windowStartPos);
}
}
}
+ long lastDouleTapTick;
+ const long allowTripleTapTimeSpan = 500;
void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e)
{
bool touched = e.PointerDeviceType == PointerDeviceType.Touch;
this.Document.SelectGrippers.BottomLeft.Enabled = false;
this.Document.SelectGrippers.BottomRight.Enabled = touched;
this.JumpCaret(e.Position);
- if (e.TapCount == 2)
+ if(e.TapCount == 1 && System.DateTime.Now.Ticks - lastDouleTapTick < allowTripleTapTimeSpan * 10000) //トリプルタップ
{
+ //タッチスクリーンで行選択した場合、アンカーインデックスを単語の先頭にしないとバグる
this.Document.SelectGrippers.BottomLeft.Enabled = touched;
- //タッチスクリーンでダブルタップした場合、アンカーインデックスを単語の先頭にしないとバグる
- this.Document.SelectWord(this.Controller.SelectionStart, touched);
+ this.Document.SelectLine(this.Controller.SelectionStart, touched);
+ this.Refresh();
+ }
+ else if(e.TapCount == 2) //ダブルタップ
+ {
+ //タッチスクリーンで単語選択した場合、アンカーインデックスを単語の先頭にしないとバグる
+ this.Document.SelectGrippers.BottomLeft.Enabled = touched;
+ if (e.Position.X < this.Render.TextArea.X)
+ this.Document.SelectLine(this.Controller.SelectionStart, touched);
+ else
+ this.Document.SelectWord(this.Controller.SelectionStart, touched);
+ this.lastDouleTapTick = System.DateTime.Now.Ticks;
this.Refresh();
}
}
else
return;
TextPoint tp = this.View.GetTextPointFromPostion(p, searchRange);
- this._Controller.MoveCaretAndSelect(tp);
+ this._Controller.MoveCaretAndSelect(tp, this.IsModiferKeyPressed(VirtualKey.LeftControl));
#if ENABLE_AUTMATION
if (this.peer != null)
this.peer.OnNotifyCaretChanged();
void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
- if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
- {
- this.Refresh();
- return;
- }
+ //LostFocusやGotFocusなどと競合するとDirect2Dでエラーが起きるので、timer_tickイベントでサイズ変更を行うことにした
+ this.requestSizeChange = true;
}
void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
void timer_Tick(object sender, object e)
{
- if (this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw)
+ this.timer.Stop();
+ if(this.requestSizeChange)
+ {
+ if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
+ {
+ //普通に再描写するとちらつく
+ this.Refresh(this.View.PageBound);
+ }
+ this.requestSizeChange = false;
+ }
+ else if (this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw)
{
this.Refresh(this.View.PageBound);
}
+ this.timer.Start();
}
private void SetDocument(Document value)
old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
this._Document.SelectionChanged -= Controller_SelectionChanged;
this._Document.LoadProgress -= Document_LoadProgress;
+ this._Document.AutoCompleteChanged -= _Document_AutoCompleteChanged;
if (this._Document.AutoComplete != null)
{
this._Document.AutoComplete.GetPostion = null;
this._Document.LayoutLines.Render = this.Render;
this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
this._Document.LoadProgress += Document_LoadProgress;
- if(this._Document.AutoComplete != null)
- {
- this._Document.AutoComplete.GetPostion = (tp,doc) =>
- {
- var p = this.View.GetPostionFromTextPoint(tp);
- int height = (int)doc.LayoutLines.GetLayout(doc.CaretPostion.row).Height;
-
- if (p.Y + AutoCompleteBox.CompleteListBoxHeight + height > doc.LayoutLines.Render.TextArea.Height)
- p.Y -= AutoCompleteBox.CompleteListBoxHeight;
- else
- p.Y += height;
- //AutoCompleteBox内ではCanvasで位置を指定しているので変換する必要がある
- var pointInWindow = Util.GetPointInWindow(p, this);
- return pointInWindow;
- };
- }
+ this._Document.AutoCompleteChanged += _Document_AutoCompleteChanged;
+ if (this._Document.AutoComplete != null && this._Document.AutoComplete.GetPostion == null)
+ this._Document_AutoCompleteChanged(this._Document, null);
//初期化が終わっていればすべて存在する
if (this.Controller != null && this.View != null)
{
this._Document.SelectionChanged += Controller_SelectionChanged;
}
+ private void _Document_AutoCompleteChanged(object sender, EventArgs e)
+ {
+ Document doc = (Document)sender;
+ doc.AutoComplete.GetPostion = (tp, e_doc) =>
+ {
+ var p = this.View.GetPostionFromTextPoint(tp);
+ int height = (int)e_doc.LayoutLines.GetLayout(e_doc.CaretPostion.row).Height;
+
+ if (p.Y + AutoCompleteBox.CompleteListBoxHeight + height > e_doc.LayoutLines.Render.TextArea.Height)
+ p.Y -= AutoCompleteBox.CompleteListBoxHeight;
+ else
+ p.Y += height;
+ //AutoCompleteBox内ではCanvasで位置を指定しているので変換する必要がある
+ var pointInWindow = Util.GetPointInWindow(p, this);
+ return pointInWindow;
+ };
+ }
+
/// <inheritdoc/>
public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
source.Render.FontSize = source.FontSize;
if (e.Property.Equals(ForegroundProperty))
source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground);
+ if (e.Property.Equals(HilightForegroundProperty))
+ source.Render.HilightForeground = D2DRenderBase.ToColor4(source.HilightForeground);
if (e.Property.Equals(BackgroundProperty))
source.Render.Background = D2DRenderBase.ToColor4(source.Background);
if (e.Property.Equals(ControlCharProperty))
DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
/// <summary>
+ /// 選択時の文字色を表す。これは依存プロパティです
+ /// </summary>
+ public Windows.UI.Color HilightForeground
+ {
+ get { return (Windows.UI.Color)GetValue(HilightForegroundProperty); }
+ set { SetValue(HilightForegroundProperty, value); }
+ }
+
+ /// <summary>
+ /// HilightForegroundForegroundの依存プロパティを表す
+ /// </summary>
+ public static readonly DependencyProperty HilightForegroundProperty =
+ DependencyProperty.Register("HilightForeground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
+
+ /// <summary>
/// 背景色を表す。これは依存プロパティです
/// </summary>
public new Windows.UI.Color Background
/// Hilightの依存プロパティを表す
/// </summary>
public static readonly DependencyProperty HilightProperty =
- DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DeepSkyBlue, OnPropertyChanged));
+ DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DodgerBlue, OnPropertyChanged));
/// <summary>
/// キーワード1の文字色を表す。これは依存プロパティです