OSDN Git Service

ae36510fd4110f6d52d580d7e957b2f1e78afd0c
[fooeditengine/FooEditEngine.git] / UWP / FooEditEngine.UWP / FooTextBox.cs
1 /*
2  * Copyright (C) 2013 FooProject
3  * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
5
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
10  */
11
12 using System;
13 using System.Text;
14 using System.ComponentModel;
15 using System.Threading.Tasks;
16 using Windows.ApplicationModel.Resources.Core;
17 using Windows.Devices.Input;
18 using Windows.System;
19 using Windows.ApplicationModel.DataTransfer;
20 using Windows.Foundation;
21 using Windows.UI;
22 using Windows.UI.Input;
23 using Windows.UI.Core;
24 using Windows.UI.Popups;
25 using Windows.UI.Text;
26 using Windows.UI.Xaml.Media;
27 using Windows.UI.Xaml;
28 using Windows.UI.Xaml.Controls;
29 using Windows.UI.Xaml.Controls.Primitives;
30 using Windows.UI.Xaml.Input;
31 using Windows.UI.Text.Core;
32
33 // テンプレート コントロールのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234235 を参照してください
34 namespace FooEditEngine.UWP
35 {
36     /// <summary>
37     /// テキストボックスコントロール
38     /// </summary>
39     public sealed class FooTextBox : Control,IDisposable
40     {
41         EditView _View;
42         Controller _Controller;
43 #if !DUMMY_RENDER
44         D2DRender Render;
45 #else
46         DummyRender Render;
47 #endif
48         ScrollBar horizontalScrollBar, verticalScrollBar;
49         Windows.UI.Xaml.Shapes.Rectangle rectangle;
50         GestureRecognizer gestureRecongnizer = new GestureRecognizer();
51         CoreTextEditContext textEditContext;
52         CoreTextServicesManager textServiceManager;
53 #if ENABLE_AUTMATION
54         FooTextBoxAutomationPeer peer;
55 #endif
56         bool nowCaretMove = false;
57         bool nowCompstion = false;
58         bool requestSizeChange = false;
59         Document _Document;
60         DispatcherTimer timer = new DispatcherTimer();
61
62         const int Interval = 32;
63         const int IntervalWhenLostFocus = 160;
64
65         /// <summary>
66         /// コンストラクター
67         /// </summary>
68         public FooTextBox()
69         {
70             this.DefaultStyleKey = typeof(FooTextBox);
71             
72             this.rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
73             this.rectangle.Margin = this.Padding;
74 #if !DUMMY_RENDER
75             this.Render = new D2DRender(this,this.rectangle);
76 #else
77             this.Render = new DummyRender();
78 #endif
79
80             this.Document = new Document();
81
82             this._View = new EditView(this.Document, this.Render, new Padding(5, 5, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth));
83             this._View.SrcChanged += View_SrcChanged;
84             this._View.InsertMode = this.InsertMode;
85             this.Document.DrawLineNumber = this.DrawLineNumber;
86             this._View.HideCaret = !this.DrawCaret;
87             this._View.HideLineMarker = !this.DrawCaretLine;
88             this.Document.HideRuler = !this.DrawRuler;
89             this.Document.UrlMark = this.MarkURL;
90             this.Document.TabStops = this.TabChars;
91
92             this._Controller = new Controller(this.Document, this._View);
93
94             this.gestureRecongnizer.GestureSettings = GestureSettings.Drag | 
95                 GestureSettings.RightTap | 
96                 GestureSettings.Tap | 
97                 GestureSettings.DoubleTap |
98                 GestureSettings.ManipulationTranslateX | 
99                 GestureSettings.ManipulationTranslateY |
100                 GestureSettings.ManipulationScale |
101                 GestureSettings.ManipulationTranslateInertia |
102                 GestureSettings.ManipulationScaleInertia;
103             this.gestureRecongnizer.RightTapped += gestureRecongnizer_RightTapped;
104             this.gestureRecongnizer.Tapped += gestureRecongnizer_Tapped;
105             this.gestureRecongnizer.Dragging += gestureRecongnizer_Dragging;
106             this.gestureRecongnizer.ManipulationInertiaStarting += GestureRecongnizer_ManipulationInertiaStarting; ;
107             this.gestureRecongnizer.ManipulationStarted += gestureRecongnizer_ManipulationStarted;
108             this.gestureRecongnizer.ManipulationUpdated += gestureRecongnizer_ManipulationUpdated;
109             this.gestureRecongnizer.ManipulationCompleted += gestureRecongnizer_ManipulationCompleted;
110
111             this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
112             this.timer.Tick += this.timer_Tick;
113             this.timer.Start();
114
115             this.GettingFocus += FooTextBox_GettingFocus;
116             this.LosingFocus += FooTextBox_LosingFocus;
117
118             this.SizeChanged += FooTextBox_SizeChanged;
119
120             this.Loaded += FooTextBox_Loaded;
121         }
122
123         /// <summary>
124         /// ファイナライザー
125         /// </summary>
126         ~FooTextBox()
127         {
128             this.Dispose(false);
129         }
130
131         /// <summary>
132         /// アンマネージドリソースを解放する
133         /// </summary>
134         public void Dispose()
135         {
136             this.Dispose(true);
137             GC.SuppressFinalize(this);
138         }
139
140         bool Disposed = false;
141         private void Dispose(bool disposing)
142         {
143             if (this.Disposed)
144                 return;
145             if (disposing)
146             {
147                 this._View.Dispose();
148                 this.Render.Dispose();
149             }
150         }
151
152         /// <summary>
153         /// ドキュメントを選択する
154         /// </summary>
155         /// <param name="start">開始インデックス</param>
156         /// <param name="length">長さ</param>
157         public void Select(int start, int length)
158         {
159             this.Document.Select(start, length);
160         }
161
162         /// <summary>
163         /// キャレットを指定した行に移動させます
164         /// </summary>
165         /// <param name="index">インデックス</param>
166         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
167         public void JumpCaret(int index)
168         {
169             this._Controller.JumpCaret(index);
170         }
171         /// <summary>
172         /// キャレットを指定した行と桁に移動させます
173         /// </summary>
174         /// <param name="row">行番号</param>
175         /// <param name="col">桁</param>
176         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
177         public void JumpCaret(int row, int col)
178         {
179             this._Controller.JumpCaret(row, col);
180         }
181
182         /// <summary>
183         /// 選択中のテキストをクリップボードにコピーします
184         /// </summary>
185         public void Copy()
186         {
187             string text = this._Controller.SelectedText;
188             if (text != null && text != string.Empty)
189             {
190                 DataPackage dataPackage = new DataPackage();
191                 dataPackage.RequestedOperation = DataPackageOperation.Copy;
192                 dataPackage.SetText(text);
193
194                 Clipboard.SetContent(dataPackage); 
195             }
196         }
197
198         /// <summary>
199         /// 選択中のテキストをクリップボードに切り取ります
200         /// </summary>
201         public void Cut()
202         {
203             string text = this._Controller.SelectedText;
204             if (text != null && text != string.Empty)
205             {
206                 DataPackage dataPackage = new DataPackage();
207                 dataPackage.RequestedOperation = DataPackageOperation.Copy;
208                 dataPackage.SetText(text);
209
210                 Clipboard.SetContent(dataPackage);
211                 
212                 this._Controller.SelectedText = "";
213             }
214         }
215
216         /// <summary>
217         /// 選択中のテキストを貼り付けます
218         /// </summary>
219         public async Task PasteAsync()
220         {
221             var dataPackageView = Clipboard.GetContent();
222             if (dataPackageView.Contains(StandardDataFormats.Text))
223             {
224                 try
225                 {
226                     this._Controller.SelectedText = await dataPackageView.GetTextAsync();
227                 }catch(Exception e)
228                 {
229                     System.Diagnostics.Debug.WriteLine("past error:" + e.Message);
230                 }
231             }
232         }
233
234         /// <summary>
235         /// すべて選択する
236         /// </summary>
237         public void SelectAll()
238         {
239             this.Document.Select(0, this.Document.Length);
240         }
241
242         /// <summary>
243         /// 選択を解除する
244         /// </summary>
245         public void DeSelectAll()
246         {
247             this._Controller.DeSelectAll();
248         }
249
250         /// <summary>
251         /// 対応する座標を返します
252         /// </summary>
253         /// <param name="tp">テキストポイント</param>
254         /// <returns>座標</returns>
255         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
256         public Windows.Foundation.Point GetPostionFromTextPoint(TextPoint tp)
257         {
258             if (this.Document.FireUpdateEvent == false)
259                 throw new InvalidOperationException("");
260             return this._View.GetPostionFromTextPoint(tp);
261         }
262
263         /// <summary>
264         /// 対応するテキストポイントを返します
265         /// </summary>
266         /// <param name="p">クライアント領域の原点を左上とする座標</param>
267         /// <returns>テキストポイント</returns>
268         public TextPoint GetTextPointFromPostion(Windows.Foundation.Point p)
269         {
270             if (this.Document.FireUpdateEvent == false)
271                 throw new InvalidOperationException("");
272             return this._View.GetTextPointFromPostion(p);
273         }
274
275         /// <summary>
276         /// 行の高さを取得します
277         /// </summary>
278         /// <param name="row">レイアウト行</param>
279         /// <returns>行の高さ</returns>
280         public double GetLineHeight(int row)
281         {
282             if (this.Document.FireUpdateEvent == false)
283                 throw new InvalidOperationException("");
284             return this._View.LayoutLines.GetLayout(row).Height; ;
285         }
286
287         /// <summary>
288         /// インデックスに対応する座標を得ます
289         /// </summary>
290         /// <param name="index">インデックス</param>
291         /// <returns>座標を返す</returns>
292         public Windows.Foundation.Point GetPostionFromIndex(int index)
293         {
294             if (this.Document.FireUpdateEvent == false)
295                 throw new InvalidOperationException("");
296             TextPoint tp = this._View.GetLayoutLineFromIndex(index);
297             return this._View.GetPostionFromTextPoint(tp);
298         }
299
300         /// <summary>
301         /// 座標からインデックスに変換します
302         /// </summary>
303         /// <param name="p">座標</param>
304         /// <returns>インデックスを返す</returns>
305         public int GetIndexFromPostion(Windows.Foundation.Point p)
306         {
307             if (this.Document.FireUpdateEvent == false)
308                 throw new InvalidOperationException("");
309             TextPoint tp = this._View.GetTextPointFromPostion(p);
310             return this._View.GetIndexFromLayoutLine(tp);
311         }
312         
313
314         /// <summary>
315         /// 再描写する
316         /// </summary>
317         public void Refresh(bool immidately=true)
318         {
319             if(immidately)
320                 this.Refresh(this._View.PageBound);
321             else
322                 this.Document.RequestRedraw();
323         }
324
325         /// <summary>
326         /// レイアウト行をすべて破棄し、再度レイアウトを行う
327         /// </summary>
328         public void PerfomLayouts()
329         {
330             this.Document.PerformLayout();
331         }
332
333         /// <summary>
334         /// 指定行までスクロールする
335         /// </summary>
336         /// <param name="row">行</param>
337         /// <param name="alignTop">指定行を画面上に置くなら真。そうでないなら偽</param>
338         public void ScrollIntoView(int row, bool alignTop)
339         {
340             this._View.ScrollIntoView(row, alignTop);
341         }
342
343         /// <summary>
344         /// ファイルからドキュメントを構築する
345         /// </summary>
346         /// <param name="sr">StremReader</param>
347         /// <returns>Taskオブジェクト</returns>
348         public async Task LoadFileAsync(System.IO.StreamReader sr, System.Threading.CancellationTokenSource token)
349         {
350             await this.Document.LoadAsync(sr, token);
351         }
352
353         private void Document_LoadProgress(object sender, ProgressEventArgs e)
354         {
355             if(e.state == ProgressState.Start)
356             {
357                 this.IsEnabled = false;
358             }
359             else if(e.state == ProgressState.Complete)
360             {
361                 CoreTextRange modified_range = new CoreTextRange();
362                 modified_range.StartCaretPosition = 0;
363                 modified_range.EndCaretPosition = 0;
364                 //キャレット位置はロード前と同じにしないと違和感を感じる
365                 if (this.textEditContext != null)
366                     this.textEditContext.NotifyTextChanged(modified_range, this.Document.Length, modified_range);
367
368                 if (this.verticalScrollBar != null)
369                     this.verticalScrollBar.Maximum = this._View.LayoutLines.Count;
370                 this.IsEnabled = true;
371                 this.Refresh(false);
372             }
373         }
374
375         /// <summary>
376         /// ドキュメントの内容をファイルに保存する
377         /// </summary>
378         /// <param name="sw">StreamWriter</param>
379         /// <param name="enc">エンコード</param>
380         /// <returns>Taskオブジェクト</returns>
381         public async Task SaveFile(System.IO.StreamWriter sw, System.Threading.CancellationTokenSource token)
382         {
383             await this.Document.SaveAsync(sw, token);
384         }
385
386 #region command
387         void CopyCommand()
388         {
389             this.Copy();
390         }
391
392         void CutCommand()
393         {
394             this.Cut();
395             this.Refresh();
396         }
397
398         async Task PasteCommand()
399         {
400             await this.PasteAsync();
401             this.Refresh();
402         }
403
404 #endregion
405
406 #region event
407
408 #if ENABLE_AUTMATION
409         /// <inheritdoc/>
410         protected override Windows.UI.Xaml.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
411         {
412             this.peer = new FooTextBoxAutomationPeer(this);
413             return this.peer;
414         }
415 #endif
416         /// <inheritdoc/>
417         protected override void OnApplyTemplate()
418         {
419             base.OnApplyTemplate();
420
421             Grid grid = this.GetTemplateChild("PART_Grid") as Grid;
422             if (grid != null)
423             {
424                 Grid.SetRow(this.rectangle, 0);
425                 Grid.SetColumn(this.rectangle, 0);
426                 grid.Children.Add(this.rectangle);
427             }
428
429             this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
430             if (this.horizontalScrollBar != null)
431             {
432                 this.horizontalScrollBar.SmallChange = 10;
433                 this.horizontalScrollBar.LargeChange = 100;
434                 this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1;
435                 this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll);
436             }
437             this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;
438             if (this.verticalScrollBar != null)
439             {
440                 this.verticalScrollBar.SmallChange = 1;
441                 this.verticalScrollBar.LargeChange = 10;
442                 this.verticalScrollBar.Maximum = this._View.LayoutLines.Count;
443                 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
444             }
445         }
446
447         private void FooTextBox_LosingFocus(UIElement sender, LosingFocusEventArgs args)
448         {
449             this.RemoveTextContext();
450             
451             if (this.textServiceManager != null)
452             {
453                 this.textServiceManager.InputLanguageChanged -= TextServiceManager_InputLanguageChanged;
454                 this.textServiceManager = null;
455             }
456
457             System.Diagnostics.Debug.WriteLine("losing focus");
458         }
459
460         private async void FooTextBox_GettingFocus(UIElement sender, GettingFocusEventArgs args)
461         {
462             System.Diagnostics.Debug.WriteLine("getting focus");
463             if (this.textServiceManager == null)
464             {
465                 await Task.Delay(500);
466                 this.textServiceManager = CoreTextServicesManager.GetForCurrentView();
467                 this.textServiceManager.InputLanguageChanged += TextServiceManager_InputLanguageChanged;
468             }
469
470             this.CreateTextContext();
471         }
472
473         /// <inheritdoc/>
474         protected override void OnGotFocus(RoutedEventArgs e)
475         {
476             base.OnGotFocus(e);
477
478             System.Diagnostics.Debug.WriteLine("got focus");
479
480             this._View.IsFocused = true;
481             this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
482             this.Refresh(false);
483         }
484
485         private void TextServiceManager_InputLanguageChanged(CoreTextServicesManager sender, object args)
486         {
487             System.Diagnostics.Debug.WriteLine("input language changed input script:"+  this.textServiceManager.InputLanguage.Script);
488         }
489
490        /// <inheritdoc/>
491         protected override void OnLostFocus(RoutedEventArgs e)
492         {
493             base.OnLostFocus(e);
494
495             System.Diagnostics.Debug.WriteLine("lost focus");
496             
497             this._View.IsFocused = false;
498             this.Refresh(false);
499             this.timer.Interval = new TimeSpan(0, 0, 0, 0, IntervalWhenLostFocus);
500         }
501
502         private void CreateTextContext()
503         {
504             if(this.textServiceManager != null)
505             {
506                 this.textEditContext = this.textServiceManager.CreateEditContext();
507                 this.textEditContext.InputScope = CoreTextInputScope.Text;
508                 this.textEditContext.CompositionStarted += TextEditContext_CompositionStarted;
509                 this.textEditContext.CompositionCompleted += TextEditContext_CompositionCompleted;
510                 this.textEditContext.LayoutRequested += TextEditContext_LayoutRequested;
511                 this.textEditContext.TextUpdating += TextEditContext_TextUpdating;
512                 this.textEditContext.TextRequested += TextEditContext_TextRequested;
513                 this.textEditContext.SelectionRequested += TextEditContext_SelectionRequested;
514                 this.textEditContext.SelectionUpdating += TextEditContext_SelectionUpdating;
515                 this.textEditContext.FormatUpdating += TextEditContext_FormatUpdating;
516                 this.textEditContext.FocusRemoved += TextEditContext_FocusRemoved;
517                 this.textEditContext.NotifyFocusLeaveCompleted += TextEditContext_NotifyFocusLeaveCompleted;
518                 this.textEditContext.NotifyFocusEnter();
519             }
520         }
521
522         private void RemoveTextContext()
523         {
524             if(this.textEditContext != null)
525             {
526                 this.textEditContext.NotifyFocusLeave();
527                 this.textEditContext.CompositionStarted -= TextEditContext_CompositionStarted;
528                 this.textEditContext.CompositionCompleted -= TextEditContext_CompositionCompleted;
529                 this.textEditContext.LayoutRequested -= TextEditContext_LayoutRequested;
530                 this.textEditContext.TextUpdating -= TextEditContext_TextUpdating;
531                 this.textEditContext.TextRequested -= TextEditContext_TextRequested;
532                 this.textEditContext.SelectionRequested -= TextEditContext_SelectionRequested;
533                 this.textEditContext.SelectionUpdating -= TextEditContext_SelectionUpdating;
534                 this.textEditContext.FormatUpdating -= TextEditContext_FormatUpdating;
535                 this.textEditContext.FocusRemoved -= TextEditContext_FocusRemoved;
536                 this.textEditContext.NotifyFocusLeaveCompleted -= TextEditContext_NotifyFocusLeaveCompleted;
537                 this.textEditContext = null;
538             }
539         }
540
541         /// <inheritdoc/>
542         protected override async void OnKeyDown(KeyRoutedEventArgs e)
543         {
544             bool isControlPressed = this.IsModiferKeyPressed(VirtualKey.Control);
545             bool isShiftPressed = this.IsModiferKeyPressed(VirtualKey.Shift);
546             bool isMovedCaret = false;
547
548             var autocomplete = this.Document.AutoComplete as AutoCompleteBox;
549             if (autocomplete != null && autocomplete.ProcessKeyDown(this, e, isControlPressed, isShiftPressed))
550                 return;
551
552             switch (e.Key)
553             {
554                 case VirtualKey.Up:
555                     this._Controller.MoveCaretVertical(-1, isShiftPressed);
556                     this.Refresh();
557                     e.Handled = true;
558                     isMovedCaret = true;
559                     break;
560                 case VirtualKey.Down:
561                     this._Controller.MoveCaretVertical(+1, isShiftPressed);
562                     this.Refresh();
563                     e.Handled = true;
564                     isMovedCaret = true;
565                     break;
566                 case VirtualKey.Left:
567                     this._Controller.MoveCaretHorizontical(-1, isShiftPressed, isControlPressed);
568                     this.Refresh();
569                     e.Handled = true;
570                     isMovedCaret = true;
571                     break;
572                 case VirtualKey.Right:
573                     this._Controller.MoveCaretHorizontical(1, isShiftPressed, isControlPressed);
574                     this.Refresh();
575                     e.Handled = true;
576                     isMovedCaret = true;
577                     break;
578                 case VirtualKey.PageUp:
579                     this._Controller.Scroll(ScrollDirection.Up, this._View.LineCountOnScreen, isShiftPressed, true);
580                     this.Refresh();
581                     isMovedCaret = true;
582                     break;
583                 case VirtualKey.PageDown:
584                     this._Controller.Scroll(ScrollDirection.Down, this._View.LineCountOnScreen, isShiftPressed, true);
585                     this.Refresh();
586                     isMovedCaret = true;
587                     break;
588                 case VirtualKey.Home:
589                     if (isControlPressed)
590                         this._Controller.JumpToHead(isShiftPressed);
591                     else
592                         this.Controller.JumpToLineHead(this.Document.CaretPostion.row,isShiftPressed);
593                     this.Refresh();
594                     isMovedCaret = true;
595                     break;
596                 case VirtualKey.End:
597                     if (isControlPressed)
598                         this._Controller.JumpToEnd(isShiftPressed);
599                     else
600                         this.Controller.JumpToLineEnd(this.Document.CaretPostion.row,isShiftPressed);
601                     this.Refresh();
602                     isMovedCaret = true;
603                     break;
604                 case VirtualKey.Tab:
605                     if (!isControlPressed)
606                     {
607                         if (this._Controller.SelectionLength == 0)
608                             this._Controller.DoInputChar('\t');
609                         else if (isShiftPressed)
610                             this._Controller.DownIndent();
611                         else
612                             this._Controller.UpIndent();
613                         this.Refresh();
614                         e.Handled = true;
615                     }
616                     break;
617                 case VirtualKey.Enter:
618                     this._Controller.DoEnterAction();
619                     this.Refresh();
620                     e.Handled = true;
621                     break;
622                 case VirtualKey.Insert:
623                     if(this._View.InsertMode)
624                         this._View.InsertMode = false;
625                     else
626                         this._View.InsertMode = true;
627                     this.Refresh();
628                     e.Handled = true;
629                     break;
630                 case VirtualKey.A:
631                     if (isControlPressed)
632                     {
633                         this.SelectAll();
634                         this.Refresh();
635                         e.Handled = true;
636                     }
637                     break;
638                 case VirtualKey.B:
639                     if (isControlPressed)
640                     {
641                         if (this._Controller.RectSelection)
642                             this._Controller.RectSelection = false;
643                         else
644                             this._Controller.RectSelection = true;
645                         this.Refresh();
646                         e.Handled = true;
647                     }
648                     break;
649                 case VirtualKey.C:
650                     if (isControlPressed)
651                     {
652                         this.CopyCommand();
653                         e.Handled = true;
654                     }
655                     break;
656                 case VirtualKey.X:
657                     if (isControlPressed)
658                     {
659                         this.CutCommand();
660                         e.Handled = true;
661                     }
662                     break;
663                 case VirtualKey.V:
664                     if (isControlPressed)
665                     {
666                         await this.PasteCommand();
667                         e.Handled = true;
668                     }
669                     break;
670                 case VirtualKey.Y:
671                     if (isControlPressed)
672                     {
673                         this.Document.UndoManager.redo();
674                         this.Refresh();
675                         e.Handled = true;
676                     }
677                     break;
678                 case VirtualKey.Z:
679                     if (isControlPressed)
680                     {
681                         this.Document.UndoManager.undo();
682                         this.Refresh();
683                         e.Handled = true;
684                     }
685                     break;
686                 case VirtualKey.Back:
687                     this._Controller.DoBackSpaceAction();
688                     this.Refresh();
689                     e.Handled = true;
690                     break;
691                 case VirtualKey.Delete:
692                     this._Controller.DoDeleteAction();
693                     this.Refresh();
694                     e.Handled = true;
695                     break;
696             }
697             base.OnKeyDown(e);
698         }
699
700         /// <inheritdoc/>
701         protected override void OnPointerPressed(PointerRoutedEventArgs e)
702         {
703             System.Diagnostics.Debug.WriteLine("pointer pressed");
704             this.CapturePointer(e.Pointer);
705             this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this));
706             e.Handled = true;
707         }
708
709         /// <inheritdoc/>
710         protected override void OnPointerMoved(PointerRoutedEventArgs e)
711         {
712             System.Diagnostics.Debug.WriteLine("pointer moved");
713             try
714             {
715                 this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
716             }catch(System.Runtime.InteropServices.COMException ex)
717             {
718                 //ピンチズームでこの例外が発生するが、回避できない
719                 System.Diagnostics.Debug.WriteLine("expection:" + ex);
720             }
721             e.Handled = true;
722
723             if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
724             {
725                 Point p = e.GetCurrentPoint(this).Position;
726                 if (this._View.HitTextArea(p.X, p.Y))
727                 {
728                     TextPoint tp = this._View.GetTextPointFromPostion(p);
729                     if (this._Controller.IsMarker(tp, HilightType.Url))
730                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Hand, 101);
731                     else
732                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.IBeam, 101);
733                 }
734                 else
735                 {
736                     Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 101);
737                 }
738             }
739         }
740
741         /// <inheritdoc/>
742         protected override void OnPointerReleased(PointerRoutedEventArgs e)
743         {
744             System.Diagnostics.Debug.WriteLine("pointer released");
745             this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this));
746             e.Handled = true;
747         }
748
749         /// <inheritdoc/>
750         protected override void OnPointerCanceled(PointerRoutedEventArgs e)
751         {
752             System.Diagnostics.Debug.WriteLine("pointer canceled");
753             this.gestureRecongnizer.CompleteGesture();
754             e.Handled = true;
755         }
756
757         /// <inheritdoc/>
758         protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
759         {
760             System.Diagnostics.Debug.WriteLine("pointer wheelchanged");
761             bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
762                 Windows.System.VirtualKeyModifiers.Shift;
763             bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
764                 Windows.System.VirtualKeyModifiers.Control;
765             this.gestureRecongnizer.ProcessMouseWheelEvent(e.GetCurrentPoint(this), shift, ctrl);
766             e.Handled = true;
767         }
768
769         private void TextEditContext_FormatUpdating(CoreTextEditContext sender, CoreTextFormatUpdatingEventArgs args)
770         {
771             if (this.Document.Length == 0 || args.IsCanceled)
772             {
773                 args.Result = CoreTextFormatUpdatingResult.Failed;
774                 return;
775             }
776             System.Diagnostics.Debug.WriteLine("core text format updating range({0}-{1}) underline type:{2} underline color:{3} reason:{4} textcolor:{5} background:{6}",
777                 args.Range.StartCaretPosition,
778                 args.Range.EndCaretPosition,
779                 args.UnderlineType,
780                 args.UnderlineColor,
781                 args.Reason,
782                 args.TextColor,
783                 args.BackgroundColor
784                 );
785             HilightType type = HilightType.None;
786             Color color = new Color(this.Foreground.A,this.Foreground.R,this.Foreground.G,this.Foreground.R);
787             bool isBoldLine = false;
788             switch (args.UnderlineType)
789             {
790                 case UnderlineType.Dotted:
791                     type = HilightType.Dot;
792                     break;
793                 case UnderlineType.Single:
794                     type = HilightType.Sold;
795                     break;
796                 case UnderlineType.Dash:
797                     type = HilightType.Dash;
798                     break;
799                 case UnderlineType.Wave:
800                     type = HilightType.Squiggle;
801                     break;
802                 case UnderlineType.Thin:
803                     type = HilightType.Sold;
804                     break;
805                 case UnderlineType.Thick:
806                     type = HilightType.Sold;
807                     isBoldLine = true;
808                     break;
809             }
810             int start = args.Range.StartCaretPosition;
811             int lengt = args.Range.EndCaretPosition - args.Range.StartCaretPosition;
812             this.Document.SetMarker(MarkerIDs.IME, Marker.Create(start, lengt, type, color, isBoldLine));
813
814             if (args.Reason == CoreTextFormatUpdatingReason.CompositionTargetConverted)
815             {
816                 this._View.AdjustSrc(args.Range.StartCaretPosition);
817             }
818             this.Refresh();
819
820             args.Result = CoreTextFormatUpdatingResult.Succeeded;
821         }
822
823         private void TextEditContext_TextRequested(CoreTextEditContext sender, CoreTextTextRequestedEventArgs args)
824         {
825             CoreTextTextRequest req = args.Request;
826
827             if (this.Document.Length == 0 || req.IsCanceled)
828             {
829                 return;
830             }
831
832             int start = req.Range.StartCaretPosition;
833             int end = req.Range.EndCaretPosition;
834             if (end > this.Document.Length)
835                 end = this.Document.Length;
836
837             int length = end - start;
838
839             System.Diagnostics.Debug.WriteLine("req text start:{0} length:{1}", start, length);
840
841             //キャレット位置も含むので+1する必要はない
842             req.Text = this.Document.ToString(start,length);
843         }
844
845         private void TextEditContext_LayoutRequested(CoreTextEditContext sender, CoreTextLayoutRequestedEventArgs args)
846         {
847             //変換候補の範囲を取得する
848             Point startPos, endPos;
849             int i_startIndex = args.Request.Range.StartCaretPosition;
850             int i_endIndex = args.Request.Range.EndCaretPosition;
851
852             if(args.Request.IsCanceled)
853             {
854                 return;
855             }
856
857             System.Diagnostics.Debug.WriteLine("core text layoutreq range({0}-{1})",i_startIndex,i_endIndex);
858
859             if (i_startIndex != -1 && i_endIndex != -1)
860             {
861                 TextStoreHelper.GetStringExtent(this.Document, this._View, i_startIndex, i_endIndex, out startPos, out endPos);
862
863                 double scale = Util.GetScale();
864
865                 //Core.Textはスクリーン座標に変換してくれないので自前で変換する(しかも、デバイス依存の座標で返さないといけない)
866                 var screenStartPos = Util.GetScreentPoint(startPos, this).Scale(scale);
867                 var screenEndPos = Util.GetScreentPoint(endPos, this).Scale(scale);
868                 args.Request.LayoutBounds.TextBounds = new Rect(
869                     screenStartPos.X,
870                     screenStartPos.Y,
871                     Math.Max(0,screenEndPos.X - screenStartPos.X),  //折り返されている場合、負になることがある
872                     screenEndPos.Y - screenStartPos.Y);
873             }
874
875             //コントロールの範囲を取得する
876             var controlTopLeft = new Point(0, 0);
877             var controlBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
878
879             var gt = this.TransformToVisual(Window.Current.Content);
880             controlTopLeft = gt.TransformPoint(controlTopLeft);
881             controlBottomRight = gt.TransformPoint(controlBottomRight);
882
883             args.Request.LayoutBounds.ControlBounds = new Rect(
884                 controlTopLeft.X,
885                 controlTopLeft.Y,
886                 controlBottomRight.X - controlTopLeft.X,
887                 controlBottomRight.Y - controlTopLeft.Y
888                 );
889         }
890
891         private void TextEditContext_SelectionRequested(CoreTextEditContext sender, CoreTextSelectionRequestedEventArgs args)
892         {
893             if(args.Request.IsCanceled || this.Document.Length == 0)
894             {
895                 return;
896             }
897             TextRange currentSelection = new TextRange();
898             TextStoreHelper.GetSelection(this._Controller, this._View.Selections, out currentSelection);
899
900             CoreTextRange currentSelectionRange = new CoreTextRange();
901             currentSelectionRange.StartCaretPosition = currentSelection.Index;
902             currentSelectionRange.EndCaretPosition = currentSelection.Index + currentSelection.Length;
903             args.Request.Selection = currentSelectionRange;
904             System.Diagnostics.Debug.WriteLine("req selection start:{0} end:{1}", currentSelectionRange.StartCaretPosition, currentSelectionRange.EndCaretPosition);
905         }
906
907         private void TextEditContext_SelectionUpdating(CoreTextEditContext sender, CoreTextSelectionUpdatingEventArgs args)
908         {
909             if(this.Document.Length == 0 || args.IsCanceled)
910             {
911                 args.Result = CoreTextSelectionUpdatingResult.Failed;
912                 return;
913             }
914             CoreTextRange sel = args.Selection;
915             System.Diagnostics.Debug.WriteLine("update selection start:{0} end:{1}", sel.StartCaretPosition, sel.EndCaretPosition);
916             TextStoreHelper.SetSelectionIndex(this.Controller, this._View, sel.StartCaretPosition, sel.EndCaretPosition);
917             args.Result = CoreTextSelectionUpdatingResult.Succeeded;
918             this.Refresh();
919         }
920
921         private void TextEditContext_TextUpdating(CoreTextEditContext sender, CoreTextTextUpdatingEventArgs args)
922         {
923             this.nowCompstion = true;
924
925             System.Diagnostics.Debug.WriteLine("update text (modify start:{0} end:{1}) text:{2} (new sel start:{0} end:{1})",
926                 args.Range.StartCaretPosition, 
927                 args.Range.EndCaretPosition, 
928                 args.Text, 
929                 args.NewSelection.StartCaretPosition, 
930                 args.NewSelection.EndCaretPosition);
931             bool isTip = args.InputLanguage.Script == "Latan";
932             CoreTextRange sel = args.Range;
933             TextStoreHelper.SetSelectionIndex(this.Controller, this._View, sel.StartCaretPosition, sel.EndCaretPosition);
934             TextStoreHelper.InsertTextAtSelection(this._Controller, args.Text, isTip);
935             this.Refresh();
936             args.Result = CoreTextTextUpdatingResult.Succeeded;
937
938             this.nowCompstion = false;
939         }
940
941         private void TextEditContext_CompositionCompleted(CoreTextEditContext sender, CoreTextCompositionCompletedEventArgs args)
942         {
943             System.Diagnostics.Debug.WriteLine("end compostion");
944             TextStoreHelper.EndCompostion(this.Document);
945             this.Document.RemoveAllMarker(MarkerIDs.IME);
946             this.Refresh();
947         }
948
949         private void TextEditContext_CompositionStarted(CoreTextEditContext sender, CoreTextCompositionStartedEventArgs args)
950         {
951             System.Diagnostics.Debug.WriteLine("start compstion");
952             TextStoreHelper.StartCompstion(this.Document);
953         }
954
955         private void TextEditContext_NotifyFocusLeaveCompleted(CoreTextEditContext sender, object args)
956         {
957             System.Diagnostics.Debug.WriteLine("notify focus leaved");
958         }
959
960         private void TextEditContext_FocusRemoved(CoreTextEditContext sender, object args)
961         {
962             System.Diagnostics.Debug.WriteLine("focus leaved");
963         }
964
965         void Controller_SelectionChanged(object sender, EventArgs e)
966         {
967             if (this._Controller == null)
968                 return;
969
970             //こうしないと選択できなくなってしまう
971             this.nowCaretMove = true;
972             SetValue(SelectedTextProperty, this._Controller.SelectedText);
973             SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
974             SetValue(CaretPostionPropertyKey, this.Document.CaretPostion);
975             this.nowCaretMove = false;
976
977             if(!this.nowCompstion)
978             {
979                 TextRange currentSelection = new TextRange();
980                 TextStoreHelper.GetSelection(this._Controller, this._View.Selections, out currentSelection);
981
982                 CoreTextRange currentSelectionRange = new CoreTextRange();
983                 currentSelectionRange.StartCaretPosition = currentSelection.Index;
984                 currentSelectionRange.EndCaretPosition = currentSelection.Index + currentSelection.Length;
985
986                 System.Diagnostics.Debug.WriteLine("notify selection start:{0} end:{1}", currentSelectionRange.StartCaretPosition, currentSelectionRange.EndCaretPosition);
987                 //変換中に呼び出してはいけない
988                 if (this.textEditContext != null)
989                     this.textEditContext.NotifySelectionChanged(currentSelectionRange);
990             }
991 #if ENABLE_AUTMATION
992             if (this.peer != null)
993                 this.peer.OnNotifyCaretChanged();
994 #endif
995         }
996
997         Gripper hittedGripper;
998         void gestureRecongnizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs e)
999         {
1000             //Updateedの段階でヒットテストしてしまうとグリッパーを触ってもヒットしないことがある
1001             this.hittedGripper = this._View.HitGripperFromPoint(e.Position);
1002         }
1003
1004         private void GestureRecongnizer_ManipulationInertiaStarting(GestureRecognizer sender, ManipulationInertiaStartingEventArgs args)
1005         {
1006             //sender.InertiaTranslationDeceleration = 0.001f;
1007             //sender.InertiaExpansionDeceleration = 100.0f * 96.0f / 1000.0f;
1008             //sender.InertiaRotationDeceleration = 720.0f / (1000.0f * 1000.0f);
1009         }
1010
1011         void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e)
1012         {
1013             if (e.Delta.Scale < 1)
1014             {
1015                 double newSize = this.Render.FontSize - 1;
1016                 if (newSize < 1)
1017                     newSize = 1;
1018                 this.Render.FontSize = newSize;
1019                 this.Refresh();
1020                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
1021                 return;
1022             }
1023
1024             if (e.Delta.Scale > 1)
1025             {
1026                 double newSize = this.Render.FontSize + 1;
1027                 if (newSize > 72)
1028                     newSize = 72;
1029                 this.Render.FontSize = newSize;
1030                 this.Refresh();
1031                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
1032                 return;
1033             }
1034
1035             if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper))
1036             {
1037                 this.Refresh();                
1038                 return;
1039             }
1040             
1041             Point translation = e.Delta.Translation;
1042
1043             //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい
1044             if (Math.Abs(e.Cumulative.Translation.X) < Math.Abs(e.Cumulative.Translation.Y))
1045             {
1046                 int deltay = (int)Math.Abs(Math.Ceiling(translation.Y));
1047                 if (translation.Y < 0)
1048                     this._Controller.ScrollByPixel(ScrollDirection.Down, deltay, false, false);
1049                 else
1050                     this._Controller.ScrollByPixel(ScrollDirection.Up, deltay, false, false);
1051                 this.Refresh();
1052                 return;
1053             }
1054
1055             int deltax = (int)Math.Abs(Math.Ceiling(translation.X));
1056             if (deltax != 0)
1057             {
1058                 if (translation.X < 0)
1059                     this._Controller.Scroll(ScrollDirection.Left, deltax, false, false);
1060                 else
1061                     this._Controller.Scroll(ScrollDirection.Right, deltax, false, false);
1062                 this.Refresh();
1063             }
1064         }
1065
1066         void gestureRecongnizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs e)
1067         {
1068         }
1069
1070         async void gestureRecongnizer_RightTapped(GestureRecognizer sender, RightTappedEventArgs e)
1071         {
1072             ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.UWP/Resources");
1073             ResourceContext context = ResourceContext.GetForCurrentView();
1074             if (this._View.HitTextArea(e.Position.X, e.Position.Y))
1075             {
1076                 FooContextMenuEventArgs args = new FooContextMenuEventArgs(e.Position);
1077                 if (this.ContextMenuOpening != null)
1078                     this.ContextMenuOpening(this, args);
1079                 if (!args.Handled)
1080                 {
1081                     PopupMenu ContextMenu = new PopupMenu();
1082                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CopyMenuName", context).ValueAsString, (command) =>
1083                     {
1084                         this.CopyCommand();
1085                     }));
1086                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CutMenuName", context).ValueAsString, (command) =>
1087                     {
1088                         this.CutCommand();
1089                     }));
1090                     ContextMenu.Commands.Add(new UICommand(map.GetValue("PasteMenuName", context).ValueAsString, async (command) =>
1091                     {
1092                         await this.PasteCommand();
1093                     }));
1094                     if (this._Controller.RectSelection)
1095                     {
1096                         ContextMenu.Commands.Add(new UICommand(map.GetValue("LineSelectMenuName", context).ValueAsString, (command) =>
1097                         {
1098                             this._Controller.RectSelection = false;
1099                         }));
1100                     }
1101                     else
1102                     {
1103                         ContextMenu.Commands.Add(new UICommand(map.GetValue("RectSelectMenuName", context).ValueAsString, (command) =>
1104                         {
1105                             this._Controller.RectSelection = true;
1106                         }));
1107                     }
1108                     var windowStartPos = Util.GetPointInWindow(e.Position, this);
1109                     await ContextMenu.ShowAsync(windowStartPos);
1110                 }
1111             }
1112         }
1113
1114         long lastDouleTapTick;
1115         const long allowTripleTapTimeSpan = 500;
1116         void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e)
1117         {
1118             bool touched = e.PointerDeviceType == PointerDeviceType.Touch;
1119             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1120             this.Document.SelectGrippers.BottomRight.Enabled = touched;
1121             this.JumpCaret(e.Position);
1122             if(e.TapCount == 1 && System.DateTime.Now.Ticks - lastDouleTapTick < allowTripleTapTimeSpan * 10000)    //トリプルタップ
1123             {
1124                 //タッチスクリーンで行選択した場合、アンカーインデックスを単語の先頭にしないとバグる
1125                 this.Document.SelectGrippers.BottomLeft.Enabled = touched;
1126                 this.Document.SelectLine(this.Controller.SelectionStart, touched);
1127                 this.Refresh();
1128             }
1129             else  if(e.TapCount == 2)   //ダブルタップ
1130             {
1131                 //タッチスクリーンで単語選択した場合、アンカーインデックスを単語の先頭にしないとバグる
1132                 this.Document.SelectGrippers.BottomLeft.Enabled = touched;
1133                 if (e.Position.X < this.Render.TextArea.X)
1134                     this.Document.SelectLine(this.Controller.SelectionStart, touched);
1135                 else
1136                     this.Document.SelectWord(this.Controller.SelectionStart, touched);
1137                 this.lastDouleTapTick = System.DateTime.Now.Ticks;
1138                 this.Refresh();
1139             }
1140         }
1141
1142         void JumpCaret(Point p)
1143         {
1144             TextPoint tp = this._View.GetTextPointFromPostion(p);
1145             if (tp == TextPoint.Null)
1146                 return;
1147
1148             int index = this._View.LayoutLines.GetIndexFromTextPoint(tp);
1149
1150             FoldingItem foldingData = this._View.HitFoldingData(p.X, tp.row);
1151             if (foldingData != null)
1152             {
1153                 if (foldingData.Expand)
1154                     this._View.LayoutLines.FoldingCollection.Collapse(foldingData);
1155                 else
1156                     this._View.LayoutLines.FoldingCollection.Expand(foldingData);
1157                 this._Controller.JumpCaret(foldingData.Start, false);
1158             }
1159             else
1160             {
1161                 this._Controller.JumpCaret(tp.row, tp.col, false);
1162             }
1163             this._View.IsFocused = true;
1164             this.Focus(FocusState.Programmatic);
1165             this.Refresh();
1166         }
1167
1168         void gestureRecongnizer_Dragging(GestureRecognizer sender, DraggingEventArgs e)
1169         {
1170             Point p = e.Position;
1171             TextPointSearchRange searchRange;
1172             if (this._View.HitTextArea(p.X, p.Y))
1173                 searchRange = TextPointSearchRange.TextAreaOnly;
1174             else if (this._Controller.SelectionLength > 0)
1175                 searchRange = TextPointSearchRange.Full;
1176             else
1177                 return;
1178             TextPoint tp = this._View.GetTextPointFromPostion(p, searchRange);
1179             this._Controller.MoveCaretAndSelect(tp, this.IsModiferKeyPressed(VirtualKey.LeftControl));
1180             this.Refresh();
1181         }
1182
1183         bool IsModiferKeyPressed(VirtualKey key)
1184         {
1185             CoreVirtualKeyStates state = Window.Current.CoreWindow.GetKeyState(key);
1186             return (state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
1187         }
1188         void Refresh(Rectangle updateRect)
1189         {
1190             if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed)
1191                 return;
1192
1193             this.Render.DrawContent(this._View, this.IsEnabled, updateRect);
1194
1195             this.Document.IsRequestRedraw = false;
1196         }
1197
1198
1199         bool Resize(double width, double height)
1200         {
1201             if (width == 0 || height == 0)
1202                 throw new ArgumentOutOfRangeException();
1203             if (this.Render.Resize(this.rectangle, width, height))
1204             {
1205                 this._View.PageBound = new Rectangle(0, 0, width, height);
1206
1207                 if (this.horizontalScrollBar != null)
1208                 {
1209                     this.horizontalScrollBar.LargeChange = this._View.PageBound.Width;
1210                     this.horizontalScrollBar.Maximum = this._View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
1211                 }
1212                 if (this.verticalScrollBar != null)
1213                 {
1214                     this.verticalScrollBar.LargeChange = this._View.LineCountOnScreen;
1215                     this.verticalScrollBar.Maximum = this._View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
1216                 }
1217                 return true;
1218             }
1219             return false;
1220         }
1221
1222         void View_SrcChanged(object sender, EventArgs e)
1223         {
1224             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
1225                 return;
1226             EditView view = this._View;
1227             if (view.Src.Row > this.verticalScrollBar.Maximum)
1228                 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
1229             double absoulteX = Math.Abs(view.Src.X);
1230             if (absoulteX > this.horizontalScrollBar.Maximum)
1231                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
1232             if (view.Src.Row != this.verticalScrollBar.Value)
1233                 this.verticalScrollBar.Value = view.Src.Row;
1234             if (view.Src.X != this.horizontalScrollBar.Value)
1235                 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
1236         }
1237
1238         void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
1239         {
1240             //LostFocusやGotFocusなどと競合するとDirect2Dでエラーが起きるので、timer_tickイベントでサイズ変更を行うことにした
1241             this.requestSizeChange = true;
1242         }
1243
1244         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
1245         {
1246             if (this.horizontalScrollBar == null)
1247                 return;
1248             double toX;
1249             if (this.FlowDirection == FlowDirection.LeftToRight)
1250                 toX = this.horizontalScrollBar.Value;
1251             else
1252                 toX = -this.horizontalScrollBar.Value;
1253             this._Controller.Scroll(toX, this._View.Src.Row, false, false);
1254             this.Refresh();
1255         }
1256
1257         void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
1258         {
1259             if (this.verticalScrollBar == null)
1260                 return;
1261             int newRow = (int)this.verticalScrollBar.Value;
1262             if (newRow >= this._View.LayoutLines.Count)
1263                 return;
1264             this._Controller.Scroll(this._View.Src.X, newRow, false, false);
1265             this.Refresh();
1266         }
1267
1268         void Document_Update(object sender, DocumentUpdateEventArgs e)
1269         {
1270             if (e.type == UpdateType.Replace && !this.nowCompstion)
1271             {
1272                 CoreTextRange oldTextRange = new CoreTextRange();
1273                 oldTextRange.StartCaretPosition = e.startIndex;
1274                 oldTextRange.EndCaretPosition = e.startIndex;
1275                 //削除する範囲が1以上の場合、ドキュメントを飛び越えることはできない
1276                 //https://msdn.microsoft.com/en-us/windows/uwp/input-and-devices/custom-text-input
1277                 if (e.removeLength > 0)
1278                     oldTextRange.EndCaretPosition += e.removeLength;
1279
1280                 TextRange currentSelection = new TextRange();
1281                 TextStoreHelper.GetSelection(this._Controller, this._View.Selections, out currentSelection);
1282
1283                 CoreTextRange newSelection = new CoreTextRange();
1284                 newSelection.StartCaretPosition = e.startIndex;
1285                 newSelection.EndCaretPosition = e.startIndex;
1286
1287                 //置き換え後の長さを指定する
1288                 //(注意:削除された文字数のほうが多い場合は0を指定しないいけない)
1289                 int newTextLength = e.insertLength;
1290
1291                 System.Diagnostics.Debug.WriteLine("notify text change (modify start:{0} end:{1}) newlength:{2} (new sel start:{3} end:{4})",
1292                     oldTextRange.StartCaretPosition, oldTextRange.EndCaretPosition, newTextLength, newSelection.StartCaretPosition, newSelection.EndCaretPosition);
1293                 //変換中に呼び出してはいけない
1294                 if(this.textEditContext != null)
1295                     this.textEditContext.NotifyTextChanged(oldTextRange, newTextLength, newSelection);
1296             }
1297 #if ENABLE_AUTMATION
1298             if (this.peer != null)
1299                 this.peer.OnNotifyTextChanged();
1300 #endif
1301         }
1302
1303         void FooTextBox_Loaded(object sender, RoutedEventArgs e)
1304         {
1305             this.Focus(FocusState.Programmatic);
1306         }
1307
1308         void timer_Tick(object sender, object e)
1309         {
1310             this.timer.Stop();
1311             if(this.requestSizeChange)
1312             {
1313                 if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
1314                 {
1315                     //普通に再描写するとちらつく
1316                     this.Refresh(this._View.PageBound);
1317                 }
1318                 this.requestSizeChange = false;
1319             }
1320             else if (this._View.LayoutLines.HilightAll() || this._View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw)
1321             {
1322                 this.Refresh(this._View.PageBound);
1323             }
1324             this.timer.Start();
1325         }
1326
1327         private void SetDocument(Document value)
1328         {
1329             if (value == null)
1330                 return;
1331
1332             Document old_doc = this._Document;
1333
1334             if (this._Document != null)
1335             {
1336                 old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
1337                 this._Document.SelectionChanged -= Controller_SelectionChanged;
1338                 this._Document.LoadProgress -= Document_LoadProgress;
1339                 this._Document.AutoCompleteChanged -= _Document_AutoCompleteChanged;
1340                 if (this._Document.AutoComplete != null)
1341                 {
1342                     this._Document.AutoComplete.GetPostion = null;
1343                     this._Document.AutoComplete = null;
1344                 }
1345
1346                 //NotifyTextChanged()を呼び出すと落ちるのでTextConextをごっそり作り替える
1347                 this.RemoveTextContext();
1348             }
1349
1350             System.Diagnostics.Debug.WriteLine("document switched");
1351
1352             this._Document = value;
1353             this._Document.LayoutLines.Render = this.Render;
1354             this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
1355             this._Document.LoadProgress += Document_LoadProgress;
1356             this._Document.AutoCompleteChanged += _Document_AutoCompleteChanged;
1357             if (this._Document.AutoComplete != null && this._Document.AutoComplete.GetPostion == null)
1358                 this._Document_AutoCompleteChanged(this._Document, null);
1359             //初期化が終わっていればすべて存在する
1360             if (this.Controller != null && this._View != null)
1361             {
1362                 this.Controller.Document = value;
1363                 this._View.Document = value;
1364
1365                 this.Controller.AdjustCaret();
1366
1367                 this.CreateTextContext();
1368
1369                 //依存プロパティとドキュメント内容が食い違っているので再設定する
1370                 this.ShowFullSpace = value.ShowFullSpace;
1371                 this.ShowHalfSpace = value.ShowHalfSpace;
1372                 this.ShowLineBreak = value.ShowLineBreak;
1373                 this.ShowTab = value.ShowTab;
1374                 this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
1375                 this.IndentMode = value.IndentMode;
1376                 this.DrawCaretLine = !value.HideLineMarker;
1377                 this.InsertMode = value.InsertMode;
1378                 this.DrawRuler = !value.HideRuler;
1379                 this.DrawLineNumber = value.DrawLineNumber;
1380                 this.MarkURL = value.UrlMark;
1381                 this.LineBreakMethod = value.LineBreak;
1382                 this.LineBreakCharCount = value.LineBreakCharCount;
1383                 this.TabChars = value.TabStops;
1384
1385                 this.Refresh();
1386             }
1387             //TextEditContext作成後に設定しないと落ちることがある
1388             this._Document.SelectionChanged += Controller_SelectionChanged;
1389         }
1390
1391         private void _Document_AutoCompleteChanged(object sender, EventArgs e)
1392         {
1393             Document doc = (Document)sender;
1394             doc.AutoComplete.GetPostion = (tp, e_doc) =>
1395             {
1396                 var p = this._View.GetPostionFromTextPoint(tp);
1397                 int height = (int)e_doc.LayoutLines.GetLayout(e_doc.CaretPostion.row).Height;
1398
1399                 if (p.Y + AutoCompleteBox.CompleteListBoxHeight + height > e_doc.LayoutLines.Render.TextArea.Height)
1400                     p.Y -= AutoCompleteBox.CompleteListBoxHeight;
1401                 else
1402                     p.Y += height;
1403                 //AutoCompleteBox内ではCanvasで位置を指定しているので変換する必要がある
1404                 var pointInWindow = Util.GetPointInWindow(p, this);
1405                 return pointInWindow;
1406             };
1407         }
1408
1409         /// <inheritdoc/>
1410         public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
1411         {
1412             FooTextBox source = (FooTextBox)sender;
1413             if(e.Property.Equals(SelectedTextProperty) && !source.nowCaretMove)
1414                 source._Controller.SelectedText = source.SelectedText;
1415             if (e.Property.Equals(DocumentProperty))
1416                 source.SetDocument(source.Document);
1417             if(e.Property.Equals(HilighterProperty))
1418                 source._View.Hilighter = source.Hilighter;
1419             if (e.Property.Equals(FoldingStrategyProperty))
1420                 source._View.LayoutLines.FoldingStrategy = source.FoldingStrategy;
1421             if (e.Property.Equals(IndentModeProperty))
1422                 source.Controller.IndentMode = source.IndentMode;
1423             if (e.Property.Equals(SelectionProperty) && !source.nowCaretMove)
1424                 source.Document.Select(source.Selection.Index,source.Selection.Length);
1425             if (e.Property.Equals(CaretPostionPropertyKey) && !source.nowCaretMove)
1426                 source.JumpCaret(source.CaretPostion.row, source.CaretPostion.col);
1427             if (e.Property.Equals(InsertModeProperty))
1428                 source._View.InsertMode = source.InsertMode;
1429             if (e.Property.Equals(TabCharsProperty))
1430                 source.Document.TabStops = source.TabChars;
1431             if (e.Property.Equals(RectSelectModeProperty))
1432                 source._Controller.RectSelection = source.RectSelectMode;
1433             if (e.Property.Equals(DrawCaretProperty))
1434                 source._View.HideCaret = !source.DrawCaret;
1435             if (e.Property.Equals(DrawCaretLineProperty))
1436                 source._View.HideLineMarker = !source.DrawCaretLine;
1437             if (e.Property.Equals(DrawLineNumberProperty))
1438                 source.Document.DrawLineNumber = source.DrawLineNumber;
1439             if (e.Property.Equals(MarkURLProperty))
1440                 source.Document.UrlMark = source.MarkURL;
1441             if (e.Property.Equals(LineBreakProperty))
1442                 source.Document.LineBreak = source.LineBreakMethod;
1443             if (e.Property.Equals(LineBreakCharCountProperty))
1444                 source.Document.LineBreakCharCount = source.LineBreakCharCount;
1445             if (e.Property.Equals(FlowDirectionProperty))
1446             {
1447                 source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft;
1448                 if (source.horizontalScrollBar != null)
1449                     source.horizontalScrollBar.FlowDirection = source.FlowDirection;
1450             }
1451             if (e.Property.Equals(DrawRulerProperty))
1452             {
1453                 source.Document.HideRuler = !source.DrawRuler;
1454                 source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col);
1455             }
1456 #if !DUMMY_RENDER
1457             if (e.Property.Equals(TextAntialiasModeProperty))
1458                 source.Render.TextAntialiasMode = source.TextAntialiasMode;
1459             if(e.Property.Equals(MagnificationPowerPropertyKey))
1460                 source.Render.FontSize = source.FontSize * source.MagnificationPower;
1461             if (e.Property.Equals(FontFamilyProperty))
1462                 source.Render.FontFamily = source.FontFamily;
1463             if (e.Property.Equals(FontStyleProperty))
1464                 source.Render.FontStyle = source.FontStyle;
1465             if (e.Property.Equals(FontWeightProperty))
1466                 source.Render.FontWeigth = source.FontWeight;
1467             if (e.Property.Equals(FontSizeProperty))
1468                 source.Render.FontSize = source.FontSize;
1469             if (e.Property.Equals(ForegroundProperty))
1470                 source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground);
1471             if (e.Property.Equals(HilightForegroundProperty))
1472                 source.Render.HilightForeground = D2DRenderBase.ToColor4(source.HilightForeground);
1473             if (e.Property.Equals(BackgroundProperty))
1474                 source.Render.Background = D2DRenderBase.ToColor4(source.Background);
1475             if (e.Property.Equals(ControlCharProperty))
1476                 source.Render.ControlChar = D2DRenderBase.ToColor4(source.ControlChar);
1477             if (e.Property.Equals(HilightProperty))
1478                 source.Render.Hilight = D2DRenderBase.ToColor4(source.Hilight);
1479             if (e.Property.Equals(Keyword1Property))
1480                 source.Render.Keyword1 = D2DRenderBase.ToColor4(source.Keyword1);
1481             if (e.Property.Equals(Keyword2Property))
1482                 source.Render.Keyword2 = D2DRenderBase.ToColor4(source.Keyword2);
1483             if (e.Property.Equals(CommentProperty))
1484                 source.Render.Comment = D2DRenderBase.ToColor4(source.Comment);
1485             if (e.Property.Equals(LiteralProperty))
1486                 source.Render.Literal = D2DRenderBase.ToColor4(source.Literal);
1487             if (e.Property.Equals(URLProperty))
1488                 source.Render.Url = D2DRenderBase.ToColor4(source.URL);
1489             if (e.Property.Equals(InsertCaretProperty))
1490                 source.Render.InsertCaret = D2DRenderBase.ToColor4(source.InsertCaret);
1491             if (e.Property.Equals(OverwriteCaretProperty))
1492                 source.Render.OverwriteCaret = D2DRenderBase.ToColor4(source.OverwriteCaret);
1493             if (e.Property.Equals(PaddingProperty))
1494                 source._View.Padding = new Padding((int)source.Padding.Left, (int)source.Padding.Top, (int)source.Padding.Right, (int)source.Padding.Bottom);
1495             if (e.Property.Equals(LineMarkerProperty))
1496                 source.Render.LineMarker = D2DRenderBase.ToColor4(source.LineMarker);
1497             if (e.Property.Equals(ShowFullSpaceProperty))
1498                 source.Render.ShowFullSpace = source.ShowFullSpace;
1499             if (e.Property.Equals(ShowHalfSpaceProperty))
1500                 source.Render.ShowHalfSpace = source.ShowHalfSpace;
1501             if (e.Property.Equals(ShowTabProperty))
1502                 source.Render.ShowTab = source.ShowTab;
1503             if (e.Property.Equals(ShowLineBreakProperty))
1504                 source.Render.ShowLineBreak = source.ShowLineBreak;
1505             if (e.Property.Equals(UpdateAreaProperty))
1506                 source.Render.UpdateArea = D2DRenderBase.ToColor4(source.UpdateArea);
1507             if (e.Property.Equals(LineNumberProperty))
1508                 source.Render.LineNumber = D2DRenderBase.ToColor4(source.LineNumber);
1509 #endif
1510         }
1511         #endregion
1512
1513         #region event
1514
1515         /// <summary>
1516         /// コンテキストメニューが表示されるときに呼び出されます
1517         /// </summary>
1518         public event EventHandler<FooContextMenuEventArgs> ContextMenuOpening;
1519
1520 #endregion
1521
1522 #region property
1523
1524         internal Controller Controller
1525         {
1526             get
1527             {
1528                 return this._Controller;
1529             }
1530         }
1531
1532         internal EditView View
1533         {
1534             get
1535             {
1536                 return this._View;
1537             }
1538         }
1539
1540         /// <summary>
1541         /// 文字列の描写に使用されるアンチエイリアシング モードを表します
1542         /// </summary>
1543         public TextAntialiasMode TextAntialiasMode
1544         {
1545             get { return (TextAntialiasMode)GetValue(TextAntialiasModeProperty); }
1546             set { SetValue(TextAntialiasModeProperty, value); }
1547         }
1548
1549         /// <summary>
1550         /// TextAntialiasModeの依存プロパティを表す
1551         /// </summary>
1552         public static readonly DependencyProperty TextAntialiasModeProperty =
1553             DependencyProperty.Register("TextAntialiasMode", typeof(TextAntialiasMode), typeof(FooTextBox), new PropertyMetadata(TextAntialiasMode.Default, OnPropertyChanged));
1554
1555         /// <summary>
1556         /// シンタックスハイライターを表す
1557         /// </summary>
1558         public IHilighter Hilighter
1559         {
1560             get { return (IHilighter)GetValue(HilighterProperty); }
1561             set { SetValue(HilighterProperty, value); }
1562         }
1563
1564         /// <summary>
1565         /// Hilighterの依存プロパティを表す
1566         /// </summary>
1567         public static readonly DependencyProperty HilighterProperty =
1568             DependencyProperty.Register("Hilighter", typeof(IHilighter), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged));
1569
1570         /// <summary>
1571         /// フォールティングを作成するインターフェイスを表す
1572         /// </summary>
1573         public IFoldingStrategy FoldingStrategy
1574         {
1575             get { return (IFoldingStrategy)GetValue(FoldingStrategyProperty); }
1576             set { SetValue(FoldingStrategyProperty, value); }
1577         }
1578
1579         /// <summary>
1580         /// FoldingStrategyの依存プロパティ
1581         /// </summary>
1582         public static readonly DependencyProperty FoldingStrategyProperty =
1583             DependencyProperty.Register("FoldingStrategy", typeof(IFoldingStrategy), typeof(FooTextBox), new PropertyMetadata(null,OnPropertyChanged));
1584
1585         /// <summary>
1586         /// マーカーパターンセットを表す
1587         /// </summary>
1588         public MarkerPatternSet MarkerPatternSet
1589         {
1590             get
1591             {
1592                 return this.Document.MarkerPatternSet;
1593             }
1594         }
1595
1596         /// <summary>
1597         /// ドキュメントを表す
1598         /// </summary>
1599         /// <remarks>切り替え後に再描写が行われます</remarks>
1600         public Document Document
1601         {
1602             get { return (Document)GetValue(DocumentProperty); }
1603             set { SetValue(DocumentProperty, value); }
1604         }
1605
1606         // Using a DependencyProperty as the backing store for Document.  This enables animation, styling, binding, etc...
1607         public static readonly DependencyProperty DocumentProperty =
1608             DependencyProperty.Register("Document", typeof(Document), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged));
1609
1610
1611
1612         /// <summary>
1613         /// レイアウト行を表す
1614         /// </summary>
1615         public LineToIndexTable LayoutLineCollection
1616         {
1617             get { return this._View.LayoutLines; }
1618         }
1619
1620         /// <summary>
1621         /// 選択中の文字列を表す
1622         /// </summary>
1623         public string SelectedText
1624         {
1625             get { return (string)GetValue(SelectedTextProperty); }
1626             set { SetValue(SelectedTextProperty, value); }
1627         }
1628
1629         /// <summary>
1630         /// SelectedTextの依存プロパティを表す
1631         /// </summary>
1632         public static readonly DependencyProperty SelectedTextProperty =
1633             DependencyProperty.Register("SelectedText", typeof(string), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged));
1634
1635         /// <summary>
1636         /// インデントの方法を表す
1637         /// </summary>
1638         public IndentMode IndentMode
1639         {
1640             get { return (IndentMode)GetValue(IndentModeProperty); }
1641             set { SetValue(IndentModeProperty, value); }
1642         }
1643
1644         /// <summary>
1645         /// IndentModeの依存プロパティを表す
1646         /// </summary>
1647         public static readonly DependencyProperty IndentModeProperty =
1648             DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab,OnPropertyChanged));
1649
1650         /// <summary>
1651         /// 選択範囲を表す
1652         /// </summary>
1653         /// <remarks>
1654         /// Lengthが0の場合はキャレット位置を表します。
1655         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
1656         /// </remarks>
1657         public TextRange Selection
1658         {
1659             get { return (TextRange)GetValue(SelectionProperty); }
1660             set { SetValue(SelectionProperty, value); }
1661         }
1662
1663         /// <summary>
1664         /// Selectionの依存プロパティを表す
1665         /// </summary>
1666         public static readonly DependencyProperty SelectionProperty =
1667             DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null, OnPropertyChanged));
1668
1669         /// <summary>
1670         /// 拡大率を表す
1671         /// </summary>
1672         public double MagnificationPower
1673         {
1674             get { return (double)GetValue(MagnificationPowerPropertyKey); }
1675             set { SetValue(MagnificationPowerPropertyKey, value); }
1676         }
1677
1678         /// <summary>
1679         /// 拡大率を表す依存プロパティ
1680         /// </summary>
1681         public static readonly DependencyProperty MagnificationPowerPropertyKey =
1682             DependencyProperty.Register("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0, OnPropertyChanged));
1683
1684         /// <summary>
1685         /// キャレット位置を表す
1686         /// </summary>
1687         public TextPoint CaretPostion
1688         {
1689             get { return (TextPoint)GetValue(CaretPostionPropertyKey); }
1690             set { SetValue(CaretPostionPropertyKey, value); }
1691         }
1692
1693         static readonly DependencyProperty CaretPostionPropertyKey =
1694             DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(new TextPoint(), OnPropertyChanged));
1695
1696         /// <summary>
1697         /// レタリング方向を表す
1698         /// </summary>
1699         public new FlowDirection FlowDirection
1700         {
1701             get { return (FlowDirection)GetValue(FlowDirectionProperty); }
1702             set { SetValue(FlowDirectionProperty, value); }
1703         }
1704
1705         /// <summary>
1706         /// レタリング方向を表す。これは依存プロパティです
1707         /// </summary>
1708         public new static readonly DependencyProperty FlowDirectionProperty =
1709             DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight,OnPropertyChanged));
1710
1711         /// <summary>
1712         /// フォントファミリーを表す
1713         /// </summary>
1714         public new FontFamily FontFamily
1715         {
1716             get { return (FontFamily)GetValue(FontFamilyProperty); }
1717             set { SetValue(FontFamilyProperty, value); }
1718         }
1719
1720         /// <summary>
1721         /// FontFamilyの依存プロパティを表す
1722         /// </summary>
1723         public new static readonly DependencyProperty FontFamilyProperty =
1724             DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(FooTextBox), new PropertyMetadata(new FontFamily("Cambria"), OnPropertyChanged));
1725
1726         /// <summary>
1727         /// フォントサイズを表す
1728         /// </summary>
1729         public new double FontSize
1730         {
1731             get { return (double)GetValue(FontSizeProperty); }
1732             set { SetValue(FontSizeProperty, value); }
1733         }
1734
1735         /// <summary>
1736         /// FontSizeの依存プロパティを表す
1737         /// </summary>
1738         public new static readonly DependencyProperty FontSizeProperty =
1739             DependencyProperty.Register("FontSize", typeof(double), typeof(FooTextBox), new PropertyMetadata(12.0,OnPropertyChanged));
1740
1741         /// <summary>
1742         /// フォントスタイルを表す
1743         /// </summary>
1744         public new FontStyle FontStyle
1745         {
1746             get { return (FontStyle)GetValue(FontStyleProperty); }
1747             set { SetValue(FontStyleProperty, value); }
1748         }
1749
1750         /// <summary>
1751         /// FontStyleの依存プロパティを表す
1752         /// </summary>
1753         public new static readonly DependencyProperty FontStyleProperty =
1754             DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(FooTextBox), new PropertyMetadata(FontStyle.Normal,OnPropertyChanged));
1755
1756         /// <summary>
1757         /// フォントの幅を表す
1758         /// </summary>
1759         public new FontWeight FontWeight
1760         {
1761             get { return (FontWeight)GetValue(FontWeightProperty); }
1762             set { SetValue(FontWeightProperty, value); }
1763         }
1764
1765         /// <summary>
1766         /// FontWeigthの依存プロパティを表す
1767         /// </summary>
1768         public new static readonly DependencyProperty FontWeightProperty =
1769             DependencyProperty.Register("FontWeigth", typeof(FontWeight), typeof(FooTextBox), new PropertyMetadata(FontWeights.Normal,OnPropertyChanged));
1770
1771         /// <summary>
1772         /// デフォルトの文字色を表す。これは依存プロパティです
1773         /// </summary>
1774         public new Windows.UI.Color Foreground
1775         {
1776             get { return (Windows.UI.Color)GetValue(ForegroundProperty); }
1777             set { SetValue(ForegroundProperty, value); }
1778         }
1779
1780         /// <summary>
1781         /// Foregroundの依存プロパティを表す
1782         /// </summary>
1783         public new static readonly DependencyProperty ForegroundProperty =
1784             DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1785
1786         /// <summary>
1787         /// 選択時の文字色を表す。これは依存プロパティです
1788         /// </summary>
1789         public Windows.UI.Color HilightForeground
1790         {
1791             get { return (Windows.UI.Color)GetValue(HilightForegroundProperty); }
1792             set { SetValue(HilightForegroundProperty, value); }
1793         }
1794
1795         /// <summary>
1796         /// HilightForegroundForegroundの依存プロパティを表す
1797         /// </summary>
1798         public static readonly DependencyProperty HilightForegroundProperty =
1799             DependencyProperty.Register("HilightForeground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
1800
1801         /// <summary>
1802         /// 背景色を表す。これは依存プロパティです
1803         /// </summary>
1804         public new Windows.UI.Color Background
1805         {
1806             get { return (Windows.UI.Color)GetValue(BackgroundProperty); }
1807             set { SetValue(BackgroundProperty, value); }
1808         }
1809
1810         /// <summary>
1811         /// Backgroundの依存プロパティを表す
1812         /// </summary>
1813         public new static readonly DependencyProperty BackgroundProperty =
1814             DependencyProperty.Register("Background", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
1815
1816         /// <summary>
1817         /// コントロールコードの文字色を表す。これは依存プロパティです
1818         /// </summary>
1819         public Windows.UI.Color ControlChar
1820         {
1821             get { return (Windows.UI.Color)GetValue(ControlCharProperty); }
1822             set { SetValue(ControlCharProperty, value); }
1823         }
1824
1825         /// <summary>
1826         /// ControlCharの依存プロパティを表す
1827         /// </summary>
1828         public static readonly DependencyProperty ControlCharProperty =
1829             DependencyProperty.Register("ControlChar", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1830
1831         /// <summary>
1832         /// 選択時の背景色を表す。これは依存プロパティです
1833         /// </summary>
1834         public Windows.UI.Color Hilight
1835         {
1836             get { return (Windows.UI.Color)GetValue(HilightProperty); }
1837             set { SetValue(HilightProperty, value); }
1838         }
1839
1840         /// <summary>
1841         /// Hilightの依存プロパティを表す
1842         /// </summary>
1843         public static readonly DependencyProperty HilightProperty =
1844             DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DodgerBlue, OnPropertyChanged));
1845
1846         /// <summary>
1847         /// キーワード1の文字色を表す。これは依存プロパティです
1848         /// </summary>
1849         public Windows.UI.Color Keyword1
1850         {
1851             get { return (Windows.UI.Color)GetValue(Keyword1Property); }
1852             set { SetValue(Keyword1Property, value); }
1853         }
1854
1855         /// <summary>
1856         /// Keyword1の依存プロパティを表す
1857         /// </summary>
1858         public static readonly DependencyProperty Keyword1Property =
1859             DependencyProperty.Register("Keyword1", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1860
1861         /// <summary>
1862         /// キーワード2の文字色を表す。これは依存プロパティです
1863         /// </summary>
1864         public Windows.UI.Color Keyword2
1865         {
1866             get { return (Windows.UI.Color)GetValue(Keyword2Property); }
1867             set { SetValue(Keyword2Property, value); }
1868         }
1869
1870         /// <summary>
1871         /// Keyword2の依存プロパティを表す
1872         /// </summary>
1873         public static readonly DependencyProperty Keyword2Property =
1874             DependencyProperty.Register("Keyword2", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DarkCyan, OnPropertyChanged));
1875
1876         /// <summary>
1877         /// コメントの文字色を表す。これは依存プロパティです
1878         /// </summary>
1879         public Windows.UI.Color Comment
1880         {
1881             get { return (Windows.UI.Color)GetValue(CommentProperty); }
1882             set { SetValue(CommentProperty, value); }
1883         }
1884
1885         /// <summary>
1886         /// Commentの依存プロパティを表す
1887         /// </summary>
1888         public static readonly DependencyProperty CommentProperty =
1889             DependencyProperty.Register("Comment", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Green, OnPropertyChanged));
1890
1891         /// <summary>
1892         /// 文字リテラルの文字色を表す。これは依存プロパティです
1893         /// </summary>
1894         public Windows.UI.Color Literal
1895         {
1896             get { return (Windows.UI.Color)GetValue(LiteralProperty); }
1897             set { SetValue(LiteralProperty, value); }
1898         }
1899
1900         /// <summary>
1901         /// Literalの依存プロパティを表す
1902         /// </summary>
1903         public static readonly DependencyProperty LiteralProperty =
1904             DependencyProperty.Register("Literal", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Brown, OnPropertyChanged));
1905
1906         /// <summary>
1907         /// URLの文字色を表す。これは依存プロパティです
1908         /// </summary>
1909         public Windows.UI.Color URL
1910         {
1911             get { return (Windows.UI.Color)GetValue(URLProperty); }
1912             set { SetValue(URLProperty, value); }
1913         }
1914
1915         /// <summary>
1916         /// URLの依存プロパティを表す
1917         /// </summary>
1918         public static readonly DependencyProperty URLProperty =
1919             DependencyProperty.Register("URL", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1920
1921         /// <summary>
1922         /// 行更新フラグの色を表す
1923         /// </summary>
1924         public Windows.UI.Color UpdateArea
1925         {
1926             get { return (Windows.UI.Color)GetValue(UpdateAreaProperty); }
1927             set { SetValue(UpdateAreaProperty, value); }
1928         }
1929
1930         /// <summary>
1931         /// UpdateAreaの依存プロパティを表す
1932         /// </summary>
1933         public static readonly DependencyProperty UpdateAreaProperty =
1934             DependencyProperty.Register("UpdateArea", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen, OnPropertyChanged));
1935
1936         /// <summary>
1937         /// ラインマーカーの色を表す
1938         /// </summary>
1939         public Windows.UI.Color LineMarker
1940         {
1941             get { return (Windows.UI.Color)GetValue(LineMarkerProperty); }
1942             set { SetValue(LineMarkerProperty, value); }
1943         }
1944
1945         /// <summary>
1946         /// LineMarkerの依存プロパティを表す
1947         /// </summary>
1948         public static readonly DependencyProperty LineMarkerProperty =
1949             DependencyProperty.Register("LineMarker", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1950
1951         /// <summary>
1952         /// 挿入モード時のキャレットの色を表す
1953         /// </summary>
1954         public Windows.UI.Color InsertCaret
1955         {
1956             get { return (Windows.UI.Color)GetValue(InsertCaretProperty); }
1957             set { SetValue(InsertCaretProperty, value); }
1958         }
1959
1960         /// <summary>
1961         /// InsertCaretの依存プロパティを表す
1962         /// </summary>
1963         public static readonly DependencyProperty InsertCaretProperty =
1964             DependencyProperty.Register("InsertCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1965
1966         /// <summary>
1967         /// 上書きモード時のキャレット職を表す
1968         /// </summary>
1969         public Windows.UI.Color OverwriteCaret
1970         {
1971             get { return (Windows.UI.Color)GetValue(OverwriteCaretProperty); }
1972             set { SetValue(OverwriteCaretProperty, value); }
1973         }
1974
1975         /// <summary>
1976         /// OverwriteCaretの依存プロパティを表す
1977         /// </summary>
1978         public static readonly DependencyProperty OverwriteCaretProperty =
1979             DependencyProperty.Register("OverwriteCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1980
1981         /// <summary>
1982         /// 行番号の色を表す
1983         /// </summary>
1984         public Windows.UI.Color LineNumber
1985         {
1986             get { return (Windows.UI.Color)GetValue(LineNumberProperty); }
1987             set { SetValue(LineNumberProperty, value); }
1988         }
1989
1990         /// <summary>
1991         /// Using a DependencyProperty as the backing store for LineNumber.  This enables animation, styling, binding, etc...
1992         /// </summary>
1993         public static readonly DependencyProperty LineNumberProperty =
1994             DependencyProperty.Register("LineNumber", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray,OnPropertyChanged));
1995
1996         /// <summary>
1997         /// 余白を表す
1998         /// </summary>
1999         public new Thickness Padding
2000         {
2001             get { return (Thickness)GetValue(PaddingProperty); }
2002             set { SetValue(PaddingProperty, value); }
2003         }
2004
2005         /// <summary>
2006         /// Paddingの依存プロパティを表す
2007         /// </summary>
2008         public new static readonly DependencyProperty PaddingProperty =
2009             DependencyProperty.Register("Padding", typeof(Thickness), typeof(FooTextBox), new PropertyMetadata(new Thickness(),OnPropertyChanged));        
2010
2011         /// <summary>
2012         /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
2013         /// </summary>
2014         public bool InsertMode
2015         {
2016             get { return (bool)GetValue(InsertModeProperty); }
2017             set { SetValue(InsertModeProperty, value); }
2018         }
2019
2020         /// <summary>
2021         /// InsertModeの依存プロパティを表す
2022         /// </summary>
2023         public static readonly DependencyProperty InsertModeProperty =
2024             DependencyProperty.Register("InsertMode",
2025             typeof(bool),
2026             typeof(FooTextBox),
2027             new PropertyMetadata(true, OnPropertyChanged));
2028
2029         /// <summary>
2030         /// タブの文字数を表す。これは依存プロパティです
2031         /// </summary>
2032         public int TabChars
2033         {
2034             get { return (int)GetValue(TabCharsProperty); }
2035             set { SetValue(TabCharsProperty, value); }
2036         }
2037
2038         /// <summary>
2039         /// TabCharsの依存プロパティを表す
2040         /// </summary>
2041         public static readonly DependencyProperty TabCharsProperty =
2042             DependencyProperty.Register("TabChars",
2043             typeof(int),
2044             typeof(FooTextBox),
2045             new PropertyMetadata(4, OnPropertyChanged));
2046
2047         /// <summary>
2048         /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
2049         /// </summary>
2050         public bool RectSelectMode
2051         {
2052             get { return (bool)GetValue(RectSelectModeProperty); }
2053             set { SetValue(RectSelectModeProperty, value); }
2054         }
2055
2056         /// <summary>
2057         /// RectSelectModeの依存プロパティを表す
2058         /// </summary>
2059         public static readonly DependencyProperty RectSelectModeProperty =
2060             DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2061
2062         /// <summary>
2063         /// 折り返しの方法を指定する
2064         /// </summary>
2065         /// <remarks>
2066         /// 変更した場合、レイアウトの再構築を行う必要があります
2067         /// </remarks>
2068         public LineBreakMethod LineBreakMethod
2069         {
2070             get { return (LineBreakMethod)GetValue(LineBreakProperty); }
2071             set { SetValue(LineBreakProperty, value); }
2072         }
2073
2074         /// <summary>
2075         /// LineBreakMethodの依存プロパティを表す
2076         /// </summary>
2077         public static readonly DependencyProperty LineBreakProperty =
2078             DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None, OnPropertyChanged));
2079
2080
2081         /// <summary>
2082         /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
2083         /// </summary>
2084         /// <remarks>
2085         /// 変更した場合、レイアウトの再構築を行う必要があります
2086         /// </remarks>
2087         public int LineBreakCharCount
2088         {
2089             get { return (int)GetValue(LineBreakCharCountProperty); }
2090             set { SetValue(LineBreakCharCountProperty, value); }
2091         }
2092
2093         /// <summary>
2094         /// LineBreakCharCountの依存プロパティを表す
2095         /// </summary>
2096         public static readonly DependencyProperty LineBreakCharCountProperty =
2097             DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80, OnPropertyChanged));        
2098
2099         /// <summary>
2100         /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
2101         /// </summary>
2102         public bool DrawCaret
2103         {
2104             get { return (bool)GetValue(DrawCaretProperty); }
2105             set { SetValue(DrawCaretProperty, value); }
2106         }
2107
2108         /// <summary>
2109         /// DrawCaretの依存プロパティを表す
2110         /// </summary>
2111         public static readonly DependencyProperty DrawCaretProperty =
2112             DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new PropertyMetadata(true, OnPropertyChanged));
2113
2114
2115         /// <summary>
2116         /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
2117         /// </summary>
2118         public bool DrawCaretLine
2119         {
2120             get { return (bool)GetValue(DrawCaretLineProperty); }
2121             set { SetValue(DrawCaretLineProperty, value); }
2122         }
2123
2124         /// <summary>
2125         /// DrawCaretLineの依存プロパティを表す
2126         /// </summary>
2127         public static readonly DependencyProperty DrawCaretLineProperty =
2128             DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2129
2130         /// <summary>
2131         /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
2132         /// </summary>
2133         public bool DrawLineNumber
2134         {
2135             get { return (bool)GetValue(DrawLineNumberProperty); }
2136             set { SetValue(DrawLineNumberProperty, value); }
2137         }
2138
2139         /// <summary>
2140         /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
2141         /// </summary>
2142         public bool DrawRuler
2143         {
2144             get { return (bool)GetValue(DrawRulerProperty); }
2145             set { SetValue(DrawRulerProperty, value); }
2146         }
2147
2148         /// <summary>
2149         /// DrawRulerの依存プロパティを表す
2150         /// </summary>
2151         public static readonly DependencyProperty DrawRulerProperty =
2152             DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2153
2154
2155         /// <summary>
2156         /// DrawLineNumberの依存プロパティを表す
2157         /// </summary>
2158         public static readonly DependencyProperty DrawLineNumberProperty =
2159             DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2160
2161         /// <summary>
2162         /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
2163         /// </summary>
2164         public bool MarkURL
2165         {
2166             get { return (bool)GetValue(MarkURLProperty); }
2167             set { SetValue(MarkURLProperty, value); }
2168         }
2169
2170         /// <summary>
2171         /// MarkURLの依存プロパティを表す
2172         /// </summary>
2173         public static readonly DependencyProperty MarkURLProperty =
2174             DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2175
2176         /// <summary>
2177         /// 全角スペースを表示するなら真。そうでないなら偽
2178         /// </summary>
2179         public bool ShowFullSpace
2180         {
2181             get { return (bool)GetValue(ShowFullSpaceProperty); }
2182             set { SetValue(ShowFullSpaceProperty, value); }
2183         }
2184
2185         /// <summary>
2186         /// ShowFullSpaceの依存プロパティを表す
2187         /// </summary>
2188         public static readonly DependencyProperty ShowFullSpaceProperty =
2189             DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2190
2191         /// <summary>
2192         /// 半角スペースを表示するなら真。そうでないなら偽
2193         /// </summary>
2194         public bool ShowHalfSpace
2195         {
2196             get { return (bool)GetValue(ShowHalfSpaceProperty); }
2197             set { SetValue(ShowHalfSpaceProperty, value); }
2198         }
2199
2200         /// <summary>
2201         /// ShowHalfSpaceの依存プロパティを表す
2202         /// </summary>
2203         public static readonly DependencyProperty ShowHalfSpaceProperty =
2204             DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2205
2206         /// <summary>
2207         /// タブを表示するなら真。そうでないなら偽
2208         /// </summary>
2209         public bool ShowTab
2210         {
2211             get { return (bool)GetValue(ShowTabProperty); }
2212             set { SetValue(ShowTabProperty, value); }
2213         }
2214
2215         /// <summary>
2216         /// ShowTabの依存プロパティを表す
2217         /// </summary>
2218         public static readonly DependencyProperty ShowTabProperty =
2219             DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
2220
2221         /// <summary>
2222         /// 改行マークを表示するなら真。そうでないなら偽
2223         /// </summary>
2224         public bool ShowLineBreak
2225         {
2226             get { return (bool)GetValue(ShowLineBreakProperty); }
2227             set { SetValue(ShowLineBreakProperty, value); }
2228         }
2229
2230         /// <summary>
2231         /// ShowLineBreakの依存プロパティを表す
2232         /// </summary>
2233         public static readonly DependencyProperty ShowLineBreakProperty =
2234             DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false,OnPropertyChanged));
2235
2236         
2237 #endregion
2238     }
2239     /// <summary>
2240     /// コンテキストメニューのイベントデーターを表す
2241     /// </summary>
2242     public class FooContextMenuEventArgs
2243     {
2244         /// <summary>
2245         /// 処理済みなら真。そうでないなら偽
2246         /// </summary>
2247         public bool Handled = false;
2248         /// <summary>
2249         /// コンテキストメニューを表示すべき座標を表す
2250         /// </summary>
2251         public Windows.Foundation.Point Postion;
2252         /// <summary>
2253         /// コンストラクター
2254         /// </summary>
2255         /// <param name="pos"></param>
2256         public FooContextMenuEventArgs(Windows.Foundation.Point pos)
2257         {
2258             this.Postion = pos;
2259         }
2260     }
2261 }