OSDN Git Service

慣性スクロールができなくなるので、OnPointerCaptureLostメソッドを上書きしないようにした&ReleasePointerCaptureを呼び出してはいけなかった
[fooeditengine/FooEditEngine.git] / Metro / FooEditEngine / 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 using System;
12 using System.Text;
13 using System.ComponentModel;
14 using System.Threading.Tasks;
15 using Windows.ApplicationModel.Resources.Core;
16 using Windows.Devices.Input;
17 using Windows.System;
18 using Windows.ApplicationModel.DataTransfer;
19 using Windows.Foundation;
20 using Windows.UI;
21 using Windows.UI.Input;
22 using Windows.UI.Core;
23 using Windows.UI.Popups;
24 using Windows.UI.Text;
25 using Windows.UI.Xaml.Media;
26 using Windows.UI.Xaml;
27 using Windows.UI.Xaml.Controls;
28 using Windows.UI.Xaml.Controls.Primitives;
29 using Windows.UI.Xaml.Input;
30 using DotNetTextStore;
31 using DotNetTextStore.UnmanagedAPI.TSF;
32 using DotNetTextStore.UnmanagedAPI.WinDef;
33
34 // テンプレート コントロールのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234235 を参照してください
35
36 namespace FooEditEngine.Metro
37 {
38     /// <summary>
39     /// テキストボックスコントロール
40     /// </summary>
41     public sealed class FooTextBox : Control,IDisposable
42     {
43         EditView View;
44         Controller _Controller;
45         D2DRender Render;
46         ScrollBar horizontalScrollBar, verticalScrollBar;
47         Windows.UI.Xaml.Shapes.Rectangle rectangle;
48         GestureRecognizer gestureRecongnizer = new GestureRecognizer();
49         TextStore2 textStore;
50         FooTextBoxAutomationPeer peer;
51         bool nowCaretMove = false;
52         DispatcherTimer timer;
53         Document _Document;
54
55         /// <summary>
56         /// コンストラクター
57         /// </summary>
58         public FooTextBox()
59         {
60             this.DefaultStyleKey = typeof(FooTextBox);
61
62             this.textStore = new TextStore2();
63             this.textStore.IsLoading += textStore_IsLoading;
64             this.textStore.IsReadOnly += textStore_IsReadOnly;
65             this.textStore.GetStringLength += () => this.Document.Length;
66             this.textStore.GetString += _textStore_GetString;
67             this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex;
68             this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex;
69             this.textStore.InsertAtSelection += _textStore_InsertAtSelection;
70             this.textStore.GetScreenExtent += _textStore_GetScreenExtent;
71             this.textStore.GetStringExtent += _textStore_GetStringExtent;
72             this.textStore.CompositionStarted += textStore_CompositionStarted;
73             this.textStore.CompositionUpdated += textStore_CompositionUpdated;
74             this.textStore.CompositionEnded += textStore_CompositionEnded;
75
76             this.rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
77             this.rectangle.Margin = this.Padding;
78             this.Render = new D2DRender(this,this.rectangle,this.textStore);
79
80             this.Document = new Document();
81
82             this.View = new EditView(this.Document, this.Render, new Padding(5, Gripper.HitAreaWidth, 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             this.Document.SelectionChanged += Controller_SelectionChanged;
94
95             this.gestureRecongnizer.GestureSettings = GestureSettings.Drag | 
96                 GestureSettings.RightTap | 
97                 GestureSettings.Tap | 
98                 GestureSettings.DoubleTap |
99                 GestureSettings.ManipulationTranslateX | 
100                 GestureSettings.ManipulationTranslateY |
101                 GestureSettings.ManipulationScale |
102                 GestureSettings.ManipulationTranslateInertia |
103                 GestureSettings.ManipulationScaleInertia;
104             this.gestureRecongnizer.RightTapped += gestureRecongnizer_RightTapped;
105             this.gestureRecongnizer.Tapped += gestureRecongnizer_Tapped;
106             this.gestureRecongnizer.Dragging += gestureRecongnizer_Dragging;
107             this.gestureRecongnizer.ManipulationInertiaStarting += GestureRecongnizer_ManipulationInertiaStarting; ;
108             this.gestureRecongnizer.ManipulationStarted += gestureRecongnizer_ManipulationStarted;
109             this.gestureRecongnizer.ManipulationUpdated += gestureRecongnizer_ManipulationUpdated;
110             this.gestureRecongnizer.ManipulationCompleted += gestureRecongnizer_ManipulationCompleted;
111
112             this.timer = new DispatcherTimer();
113             this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
114             this.timer.Tick += new EventHandler<object>(this.timer_Tick);
115             this.timer.Start();
116
117             //Viewの初期化が終わった直後に置かないと例外が発生する
118             this.Document.Update += Document_Update;
119
120             Window.Current.CoreWindow.CharacterReceived += CoreWindow_CharacterReceived;
121
122             this.SizeChanged += FooTextBox_SizeChanged;
123
124             this.Loaded += FooTextBox_Loaded;
125         }
126
127         /// <summary>
128         /// ファイナライザー
129         /// </summary>
130         ~FooTextBox()
131         {
132             this.Dispose(false);
133         }
134
135         /// <summary>
136         /// アンマネージドリソースを解放する
137         /// </summary>
138         public void Dispose()
139         {
140             this.Dispose(true);
141             GC.SuppressFinalize(this);
142         }
143
144         bool Disposed = false;
145         private void Dispose(bool disposing)
146         {
147             if (this.Disposed)
148                 return;
149             if (disposing)
150             {
151                 this.textStore.Dispose();
152                 this.View.Dispose();
153                 this.Render.Dispose();
154             }
155         }
156
157         /// <summary>
158         /// ドキュメントを選択する
159         /// </summary>
160         /// <param name="start">開始インデックス</param>
161         /// <param name="length">長さ</param>
162         public void Select(int start, int length)
163         {
164             this.Document.Select(start, length);
165         }
166
167         /// <summary>
168         /// キャレットを指定した行に移動させます
169         /// </summary>
170         /// <param name="index">インデックス</param>
171         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
172         public void JumpCaret(int index)
173         {
174             this._Controller.JumpCaret(index);
175         }
176         /// <summary>
177         /// キャレットを指定した行と桁に移動させます
178         /// </summary>
179         /// <param name="row">行番号</param>
180         /// <param name="col">桁</param>
181         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
182         public void JumpCaret(int row, int col)
183         {
184             this._Controller.JumpCaret(row, col);
185         }
186
187         /// <summary>
188         /// 選択中のテキストをクリップボードにコピーします
189         /// </summary>
190         public void Copy()
191         {
192             string text = this._Controller.SelectedText;
193             if (text != null && text != string.Empty)
194             {
195                 DataPackage dataPackage = new DataPackage();
196                 dataPackage.RequestedOperation = DataPackageOperation.Copy;
197                 dataPackage.SetText(text);
198
199                 Clipboard.SetContent(dataPackage); 
200             }
201         }
202
203         /// <summary>
204         /// 選択中のテキストをクリップボードに切り取ります
205         /// </summary>
206         public void Cut()
207         {
208             string text = this._Controller.SelectedText;
209             if (text != null && text != string.Empty)
210             {
211                 DataPackage dataPackage = new DataPackage();
212                 dataPackage.RequestedOperation = DataPackageOperation.Copy;
213                 dataPackage.SetText(text);
214
215                 Clipboard.SetContent(dataPackage);
216                 
217                 this._Controller.SelectedText = "";
218             }
219         }
220
221         /// <summary>
222         /// 選択中のテキストを貼り付けます
223         /// </summary>
224         public async Task PasteAsync()
225         {
226             var dataPackageView = Clipboard.GetContent();
227             if (dataPackageView.Contains(StandardDataFormats.Text))
228             {
229                 this._Controller.SelectedText = await dataPackageView.GetTextAsync();
230             }
231         }
232
233         /// <summary>
234         /// すべて選択する
235         /// </summary>
236         public void SelectAll()
237         {
238             this.Document.Select(0, this.Document.Length);
239         }
240
241         /// <summary>
242         /// 選択を解除する
243         /// </summary>
244         public void DeSelectAll()
245         {
246             this._Controller.DeSelectAll();
247         }
248
249         /// <summary>
250         /// 対応する座標を返します
251         /// </summary>
252         /// <param name="tp">テキストポイント</param>
253         /// <returns>座標</returns>
254         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
255         public Windows.Foundation.Point GetPostionFromTextPoint(TextPoint tp)
256         {
257             if (this.Document.FireUpdateEvent == false)
258                 throw new InvalidOperationException("");
259             return this.View.GetPostionFromTextPoint(tp);
260         }
261
262         /// <summary>
263         /// 対応するテキストポイントを返します
264         /// </summary>
265         /// <param name="p">クライアント領域の原点を左上とする座標</param>
266         /// <returns>テキストポイント</returns>
267         public TextPoint GetTextPointFromPostion(Windows.Foundation.Point p)
268         {
269             if (this.Document.FireUpdateEvent == false)
270                 throw new InvalidOperationException("");
271             return this.View.GetTextPointFromPostion(p);
272         }
273
274         /// <summary>
275         /// 行の高さを取得します
276         /// </summary>
277         /// <param name="row">レイアウト行</param>
278         /// <returns>行の高さ</returns>
279         public double GetLineHeight(int row)
280         {
281             if (this.Document.FireUpdateEvent == false)
282                 throw new InvalidOperationException("");
283             return this.View.LayoutLines.GetLayout(row).Height; ;
284         }
285
286         /// <summary>
287         /// インデックスに対応する座標を得ます
288         /// </summary>
289         /// <param name="index">インデックス</param>
290         /// <returns>座標を返す</returns>
291         public Windows.Foundation.Point GetPostionFromIndex(int index)
292         {
293             if (this.Document.FireUpdateEvent == false)
294                 throw new InvalidOperationException("");
295             TextPoint tp = this.View.GetLayoutLineFromIndex(index);
296             return this.View.GetPostionFromTextPoint(tp);
297         }
298
299         /// <summary>
300         /// 座標からインデックスに変換します
301         /// </summary>
302         /// <param name="p">座標</param>
303         /// <returns>インデックスを返す</returns>
304         public int GetIndexFromPostion(Windows.Foundation.Point p)
305         {
306             if (this.Document.FireUpdateEvent == false)
307                 throw new InvalidOperationException("");
308             TextPoint tp = this.View.GetTextPointFromPostion(p);
309             return this.View.GetIndexFromLayoutLine(tp);
310         }
311
312         /// <summary>
313         /// 再描写する
314         /// </summary>
315         public void Refresh()
316         {
317             this.Refresh(this.View.PageBound);
318         }
319
320         /// <summary>
321         /// レイアウト行をすべて破棄し、再度レイアウトを行う
322         /// </summary>
323         public void PerfomLayouts()
324         {
325             this.View.PerfomLayouts();
326         }
327
328         /// <summary>
329         /// 指定行までスクロールする
330         /// </summary>
331         /// <param name="row">行</param>
332         /// <param name="alignTop">指定行を画面上に置くなら真。そうでないなら偽</param>
333         public void ScrollIntoView(int row, bool alignTop)
334         {
335             this.View.ScrollIntoView(row, alignTop);
336         }
337
338         /// <summary>
339         /// ファイルからドキュメントを構築する
340         /// </summary>
341         /// <param name="sr">StremReader</param>
342         /// <returns>Taskオブジェクト</returns>
343         public async Task LoadFileAsync(System.IO.StreamReader sr, System.Threading.CancellationTokenSource token)
344         {
345             this.IsEnabled = false;
346             this.View.LayoutLines.IsFrozneDirtyFlag = true;
347             WinFileReader fs = new WinFileReader(sr);
348             await this.Document.LoadAsync(fs, token);
349             this.View.LayoutLines.IsFrozneDirtyFlag = false;
350             TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);
351             if (this.verticalScrollBar != null)
352                 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
353             this.View.CalculateLineCountOnScreen();
354             this.IsEnabled = true;
355         }
356
357         /// <summary>
358         /// ドキュメントの内容をファイルに保存する
359         /// </summary>
360         /// <param name="sw">StreamWriter</param>
361         /// <param name="enc">エンコード</param>
362         /// <returns>Taskオブジェクト</returns>
363         public async Task SaveFile(System.IO.StreamWriter sw, System.Threading.CancellationTokenSource token)
364         {
365             WinFileWriter fs = new WinFileWriter(sw);
366             await this.Document.SaveAsync(fs, token);
367         }
368
369         #region command
370         void CopyCommand()
371         {
372             this.Copy();
373         }
374
375         void CutCommand()
376         {
377             this.Cut();
378             this.Refresh();
379         }
380
381         async Task PasteCommand()
382         {
383             await this.PasteAsync();
384             this.Refresh();
385         }
386
387         #endregion
388
389         #region event
390         /// <inheritdoc/>
391         protected override Windows.UI.Xaml.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
392         {
393             this.peer = new FooTextBoxAutomationPeer(this);
394             return this.peer;
395         }
396
397         /// <inheritdoc/>
398         protected override void OnApplyTemplate()
399         {
400             base.OnApplyTemplate();
401
402             Grid grid = this.GetTemplateChild("PART_Grid") as Grid;
403             if (grid != null)
404             {
405                 Grid.SetRow(this.rectangle, 0);
406                 Grid.SetColumn(this.rectangle, 0);
407                 grid.Children.Add(this.rectangle);
408             }
409
410             this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
411             if (this.horizontalScrollBar != null)
412             {
413                 this.horizontalScrollBar.SmallChange = 10;
414                 this.horizontalScrollBar.LargeChange = 100;
415                 this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1;
416                 this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll);
417             }
418             this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;
419             if (this.verticalScrollBar != null)
420             {
421                 this.verticalScrollBar.SmallChange = 1;
422                 this.verticalScrollBar.LargeChange = 10;
423                 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
424                 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
425             }
426         }
427
428         /// <inheritdoc/>
429         protected override void OnGotFocus(RoutedEventArgs e)
430         {
431             base.OnGotFocus(e);
432             this.textStore.SetFocus();
433             this.View.IsFocused = true;
434             this.Refresh();
435         }
436
437         /// <inheritdoc/>
438         protected override void OnLostFocus(RoutedEventArgs e)
439         {
440             base.OnLostFocus(e);
441             this.View.IsFocused = false;
442             this.Refresh();
443         }
444
445         /// <inheritdoc/>
446         protected override async void OnKeyDown(KeyRoutedEventArgs e)
447         {
448             bool isControlPressed = this.IsModiferKeyPressed(VirtualKey.Control);
449             bool isShiftPressed = this.IsModiferKeyPressed(VirtualKey.Shift);
450             bool isMovedCaret = false;
451             switch (e.Key)
452             {
453                 case VirtualKey.Up:
454                     this._Controller.MoveCaretVertical(-1, isShiftPressed);
455                     this.Refresh();
456                     e.Handled = true;
457                     isMovedCaret = true;
458                     break;
459                 case VirtualKey.Down:
460                     this._Controller.MoveCaretVertical(+1, isShiftPressed);
461                     this.Refresh();
462                     e.Handled = true;
463                     isMovedCaret = true;
464                     break;
465                 case VirtualKey.Left:
466                     this._Controller.MoveCaretHorizontical(-1, isShiftPressed, isControlPressed);
467                     this.Refresh();
468                     e.Handled = true;
469                     isMovedCaret = true;
470                     break;
471                 case VirtualKey.Right:
472                     this._Controller.MoveCaretHorizontical(1, isShiftPressed, isControlPressed);
473                     this.Refresh();
474                     e.Handled = true;
475                     isMovedCaret = true;
476                     break;
477                 case VirtualKey.PageUp:
478                     this._Controller.Scroll(ScrollDirection.Up, this.View.LineCountOnScreen, isShiftPressed, true);
479                     this.Refresh();
480                     isMovedCaret = true;
481                     break;
482                 case VirtualKey.PageDown:
483                     this._Controller.Scroll(ScrollDirection.Down, this.View.LineCountOnScreen, isShiftPressed, true);
484                     this.Refresh();
485                     isMovedCaret = true;
486                     break;
487                 case VirtualKey.Home:
488                     if (isControlPressed)
489                         this._Controller.JumpToHead(isShiftPressed);
490                     else
491                         this.Controller.JumpToLineHead(this.Document.CaretPostion.row,isShiftPressed);
492                     this.Refresh();
493                     isMovedCaret = true;
494                     break;
495                 case VirtualKey.End:
496                     if (isControlPressed)
497                         this._Controller.JumpToEnd(isShiftPressed);
498                     else
499                         this.Controller.JumpToLineEnd(this.Document.CaretPostion.row,isShiftPressed);
500                     this.Refresh();
501                     isMovedCaret = true;
502                     break;
503                 case VirtualKey.Tab:
504                     if (!isControlPressed)
505                     {
506                         if (this._Controller.SelectionLength == 0)
507                             this._Controller.DoInputChar('\t');
508                         else if (isShiftPressed)
509                             this._Controller.DownIndent();
510                         else
511                             this._Controller.UpIndent();
512                         this.Refresh();
513                         e.Handled = true;
514                     }
515                     break;
516                 case VirtualKey.Enter:
517                     this._Controller.DoEnterAction();
518                     this.Refresh();
519                     e.Handled = true;
520                     break;
521                 case VirtualKey.Insert:
522                     if(this.View.InsertMode)
523                         this.View.InsertMode = false;
524                     else
525                         this.View.InsertMode = true;
526                     this.Refresh();
527                     e.Handled = true;
528                     break;
529                 case VirtualKey.A:
530                     if (isControlPressed)
531                     {
532                         this.SelectAll();
533                         this.Refresh();
534                         e.Handled = true;
535                     }
536                     break;
537                 case VirtualKey.B:
538                     if (isControlPressed)
539                     {
540                         if (this._Controller.RectSelection)
541                             this._Controller.RectSelection = false;
542                         else
543                             this._Controller.RectSelection = true;
544                         this.Refresh();
545                         e.Handled = true;
546                     }
547                     break;
548                 case VirtualKey.C:
549                     if (isControlPressed)
550                     {
551                         this.CopyCommand();
552                         e.Handled = true;
553                     }
554                     break;
555                 case VirtualKey.X:
556                     if (isControlPressed)
557                     {
558                         this.CutCommand();
559                         e.Handled = true;
560                     }
561                     break;
562                 case VirtualKey.V:
563                     if (isControlPressed)
564                     {
565                         await this.PasteCommand();
566                         e.Handled = true;
567                     }
568                     break;
569                 case VirtualKey.Y:
570                     if (isControlPressed)
571                     {
572                         this.Document.UndoManager.redo();
573                         this.Refresh();
574                         e.Handled = true;
575                     }
576                     break;
577                 case VirtualKey.Z:
578                     if (isControlPressed)
579                     {
580                         this.Document.UndoManager.undo();
581                         this.Refresh();
582                         e.Handled = true;
583                     }
584                     break;
585                 case VirtualKey.Back:
586                     this._Controller.DoBackSpaceAction();
587                     this.Refresh();
588                     e.Handled = true;
589                     break;
590                 case VirtualKey.Delete:
591                     this._Controller.DoDeleteAction();
592                     this.Refresh();
593                     e.Handled = true;
594                     break;
595             }
596             if (isMovedCaret && this.peer != null)
597                 this.peer.OnNotifyCaretChanged();
598             base.OnKeyDown(e);
599         }
600
601         /// <inheritdoc/>
602         protected override void OnPointerPressed(PointerRoutedEventArgs e)
603         {
604             this.CapturePointer(e.Pointer);
605             this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this));
606             e.Handled = true;
607         }
608
609         /// <inheritdoc/>
610         protected override void OnPointerMoved(PointerRoutedEventArgs e)
611         {
612             this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
613             e.Handled = true;
614
615             if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
616             {
617                 Point p = e.GetCurrentPoint(this).Position;
618                 if (this.View.HitTextArea(p.X, p.Y))
619                 {
620                     TextPoint tp = this.View.GetTextPointFromPostion(p);
621                     if (this._Controller.IsMarker(tp, HilightType.Url))
622                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Hand, 101);
623                     else
624                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.IBeam, 101);
625                 }
626                 else
627                 {
628                     Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 101);
629                 }
630             }
631         }
632
633         /// <inheritdoc/>
634         protected override void OnPointerReleased(PointerRoutedEventArgs e)
635         {
636             this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this));
637             e.Handled = true;
638         }
639
640         /// <inheritdoc/>
641         protected override void OnPointerCanceled(PointerRoutedEventArgs e)
642         {
643             this.gestureRecongnizer.CompleteGesture();
644             e.Handled = true;
645         }
646
647         /// <inheritdoc/>
648         protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
649         {
650             bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
651                 Windows.System.VirtualKeyModifiers.Shift;
652             bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
653                 Windows.System.VirtualKeyModifiers.Control;
654             this.gestureRecongnizer.ProcessMouseWheelEvent(e.GetCurrentPoint(this), shift, ctrl);
655             e.Handled = true;
656         }
657
658         void CoreWindow_CharacterReceived(CoreWindow sender, CharacterReceivedEventArgs args)
659         {
660             if (this.FocusState == FocusState.Unfocused || !this.IsEnabled)
661                 return;
662             if (args.KeyCode >= 00 && args.KeyCode <= 0x1f)
663                 return;
664             this._Controller.DoInputString(Char.ConvertFromUtf32((int)args.KeyCode));
665             this.Refresh();
666         }
667
668         bool textStore_IsReadOnly()
669         {
670             return false;
671         }
672
673         bool textStore_IsLoading()
674         {
675             return false;
676         }
677
678         void textStore_CompositionEnded()
679         {
680             TextStoreHelper.EndCompostion(this.Document);
681             this.Refresh();
682         }
683
684         void textStore_CompositionUpdated(int start, int end)
685         {
686             if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end))
687                 this.Refresh();
688         }
689         bool textStore_CompositionStarted()
690         {
691             return TextStoreHelper.StartCompstion(this.Document);
692         }
693
694         string _textStore_GetString(int start, int length)
695         {
696             return this.Document.ToString(start, length);
697         }
698
699         void _textStore_GetStringExtent(
700             int i_startIndex,
701             int i_endIndex,
702             out POINT o_topLeft,
703             out POINT o_bottomRight
704         )
705         {
706             Point startPos, endPos;
707             TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos);
708
709             float dpi;
710             this.Render.GetDpi(out dpi, out dpi);
711             double scale = dpi / 96.0;
712
713             var gt = this.TransformToVisual(Window.Current.Content);
714             startPos = gt.TransformPoint(startPos.Scale(scale));
715             endPos = gt.TransformPoint(endPos.Scale(scale));
716
717             o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);
718             o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);
719         }
720
721         void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)
722         {
723             var pointTopLeft = new Point(0, 0);
724             var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
725
726             var gt = this.TransformToVisual(Window.Current.Content);
727             pointTopLeft = gt.TransformPoint(pointTopLeft);
728             pointBottomRight = gt.TransformPoint(pointBottomRight);
729
730             o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);
731             o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);
732         }
733
734         void _textStore_GetSelectionIndex(int start_index, int max_count, out DotNetTextStore.TextSelection[] sels)
735         {
736             TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out sels);
737         }
738
739         void _textStore_SetSelectionIndex(DotNetTextStore.TextSelection[] sels)
740         {
741             TextStoreHelper.SetSelectionIndex(this._Controller, this.View, sels);
742             this.Refresh();
743         }
744
745         void _textStore_InsertAtSelection(string i_value,ref int o_stratIndex,ref int o_endIndex)
746         {
747             TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);
748             this.Refresh();
749         }
750
751         void Controller_SelectionChanged(object sender, EventArgs e)
752         {
753             //こうしないと選択できなくなってしまう
754             this.nowCaretMove = true;
755             SetValue(SelectedTextProperty, this._Controller.SelectedText);
756             SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
757             SetValue(CaretPostionPropertyKey, this.Document.CaretPostion);
758             this.nowCaretMove = false;
759             this.Document.SelectGrippers.BottomLeft.MoveByIndex(this.View, this.Controller.SelectionStart);
760             this.Document.SelectGrippers.BottomRight.MoveByIndex(this.View, this.Controller.SelectionStart + this.Controller.SelectionLength);
761             if (this.textStore.IsLocked() == false)
762                 this.textStore.NotifySelectionChanged();
763         }
764
765         Gripper hittedGripper;
766         void gestureRecongnizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs e)
767         {
768             //Updateedの段階でヒットテストしてしまうとグリッパーを触ってもヒットしないことがある
769             this.hittedGripper = this.View.HitGripperFromPoint(e.Position);
770         }
771
772         private void GestureRecongnizer_ManipulationInertiaStarting(GestureRecognizer sender, ManipulationInertiaStartingEventArgs args)
773         {
774             //sender.InertiaTranslationDeceleration = 0.001f;
775             //sender.InertiaExpansionDeceleration = 100.0f * 96.0f / 1000.0f;
776             //sender.InertiaRotationDeceleration = 720.0f / (1000.0f * 1000.0f);
777         }
778
779             void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e)
780         {
781             if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper))
782             {
783                 if (this.peer != null)
784                     this.peer.OnNotifyCaretChanged();
785                 this.Refresh();                
786                 return;
787             }
788
789             if (e.Delta.Scale < 1)
790             {
791                 double newSize = this.Render.FontSize - 1;
792                 if (newSize < 1)
793                     newSize = 1;
794                 this.Render.FontSize = newSize;
795                 this.Refresh();
796                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
797                 return;
798             }
799             
800             if (e.Delta.Scale > 1)
801             {
802                 double newSize = this.Render.FontSize + 1;
803                 if (newSize > 72)
804                     newSize = 72;
805                 this.Render.FontSize = newSize;
806                 this.Refresh();
807                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
808                 return;
809             }
810             
811             Point translation = e.Delta.Translation;
812
813             //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい
814             if (Math.Abs(e.Cumulative.Translation.X) < Math.Abs(e.Cumulative.Translation.Y))
815             {
816                 System.Diagnostics.Debug.WriteLine("tran y:{0}", translation.Y);
817                 //下に動かした場合はマイナスの値が飛んでくる、上に動かした場合はプラスの値が飛んでくる
818                 this.View.Scroll(this.Document.Src.X, this.Document.Src.Y - translation.Y);
819                 this.View.IsFocused = false;
820                 this.Document.SelectGrippers.BottomLeft.Enabled = false;
821                 this.Document.SelectGrippers.BottomRight.Enabled = false;
822                 this.Refresh();
823                 return;
824             }
825
826             int deltax = (int)Math.Abs(Math.Ceiling(translation.X));
827             if (deltax != 0)
828             {
829                 if (translation.X < 0)
830                     this._Controller.Scroll(ScrollDirection.Left, deltax, false, false);
831                 else
832                     this._Controller.Scroll(ScrollDirection.Right, deltax, false, false);
833                 this.Document.SelectGrippers.BottomLeft.Enabled = false;
834                 this.Document.SelectGrippers.BottomRight.Enabled = false;
835                 this.Refresh();
836             }
837         }
838
839         void gestureRecongnizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs e)
840         {
841         }
842
843         async void gestureRecongnizer_RightTapped(GestureRecognizer sender, RightTappedEventArgs e)
844         {
845             ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.Metro/Resources");
846             ResourceContext context = ResourceContext.GetForCurrentView();
847             if (this.View.HitTextArea(e.Position.X, e.Position.Y))
848             {
849                 FooContextMenuEventArgs args = new FooContextMenuEventArgs(e.Position);
850                 if (this.ContextMenuOpening != null)
851                     this.ContextMenuOpening(this, args);
852                 if (!args.Handled)
853                 {
854                     PopupMenu ContextMenu = new PopupMenu();
855                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CopyMenuName", context).ValueAsString, (command) =>
856                     {
857                         this.CopyCommand();
858                     }));
859                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CutMenuName", context).ValueAsString, (command) =>
860                     {
861                         this.CutCommand();
862                     }));
863                     ContextMenu.Commands.Add(new UICommand(map.GetValue("PasteMenuName", context).ValueAsString, async (command) =>
864                     {
865                         await this.PasteCommand();
866                     }));
867                     if (this._Controller.RectSelection)
868                     {
869                         ContextMenu.Commands.Add(new UICommand(map.GetValue("LineSelectMenuName", context).ValueAsString, (command) =>
870                         {
871                             this._Controller.RectSelection = false;
872                         }));
873                     }
874                     else
875                     {
876                         ContextMenu.Commands.Add(new UICommand(map.GetValue("RectSelectMenuName", context).ValueAsString, (command) =>
877                         {
878                             this._Controller.RectSelection = true;
879                         }));
880                     }
881                     await ContextMenu.ShowAsync(Util.GetScreentPoint(e.Position,this));
882                 }
883             }
884         }
885
886         void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e)
887         {
888             bool touched = e.PointerDeviceType == PointerDeviceType.Touch;
889             this.Document.SelectGrippers.BottomLeft.Enabled = false;
890             this.Document.SelectGrippers.BottomRight.Enabled = touched;
891             this.JumpCaret(e.Position);
892             System.Diagnostics.Debug.WriteLine(e.TapCount);
893             if (e.TapCount == 2)
894             {
895                 this.Document.SelectGrippers.BottomLeft.Enabled = touched;
896                 //タッチスクリーンでダブルタップした場合、アンカーインデックスを単語の先頭にしないとバグる
897                 this.Document.SelectWord(this.Controller.SelectionStart, touched);
898             }
899         }
900
901         void JumpCaret(Point p)
902         {
903             TextPoint tp = this.View.GetTextPointFromPostion(p);
904             if (tp == TextPoint.Null)
905                 return;
906
907             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
908
909             FoldingItem foldingData = this.View.HitFoldingData(p.X, tp.row);
910             if (foldingData != null)
911             {
912                 if (foldingData.Expand)
913                     this.View.LayoutLines.FoldingCollection.Collapse(foldingData);
914                 else
915                     this.View.LayoutLines.FoldingCollection.Expand(foldingData);
916                 this._Controller.JumpCaret(foldingData.Start, false);
917             }
918             else
919             {
920                 this._Controller.JumpCaret(tp.row, tp.col, false);
921             }
922             if (this.peer != null)
923                 this.peer.OnNotifyCaretChanged();
924             this.View.IsFocused = true;
925             this.Focus(FocusState.Programmatic);
926             this.Refresh();
927         }
928
929         void gestureRecongnizer_Dragging(GestureRecognizer sender, DraggingEventArgs e)
930         {
931             Point p = e.Position;
932             if (this.View.HitTextArea(p.X, p.Y))
933             {
934                 TextPoint tp = this.View.GetTextPointFromPostion(p);
935                 this._Controller.MoveCaretAndSelect(tp);
936                 if (this.peer != null)
937                     this.peer.OnNotifyCaretChanged();
938                 this.Refresh();
939             }
940         }
941
942         bool IsModiferKeyPressed(VirtualKey key)
943         {
944             CoreVirtualKeyStates state = Window.Current.CoreWindow.GetKeyState(key);
945             return (state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
946         }
947         void Refresh(Rectangle updateRect)
948         {
949             if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed)
950                 return;
951
952             this.Render.BegineDraw();
953             if (this.IsEnabled)
954                 this.View.Draw(updateRect);
955             else
956                 this.Render.FillBackground(updateRect);
957             this.Render.EndDraw();
958         }
959
960
961         bool Resize(double width, double height)
962         {
963             if (width == 0 || height == 0)
964                 throw new ArgumentOutOfRangeException();
965             if (this.Render.Resize(this.rectangle, width, height))
966             {
967                 this.View.PageBound = new Rectangle(0, 0, width, height);
968
969                 if (this.horizontalScrollBar != null)
970                 {
971                     this.horizontalScrollBar.LargeChange = this.View.PageBound.Width;
972                     this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
973                 }
974                 if (this.verticalScrollBar != null)
975                 {
976                     this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen;
977                     this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
978                 }
979                 return true;
980             }
981             return false;
982         }
983
984         void View_SrcChanged(object sender, EventArgs e)
985         {
986             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
987                 return;
988             EditView view = this.View;
989             if (view.Src.Row > this.verticalScrollBar.Maximum)
990                 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
991             double absoulteX = Math.Abs(view.Src.X);
992             if (absoulteX > this.horizontalScrollBar.Maximum)
993                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
994             if (view.Src.Row != this.verticalScrollBar.Value)
995                 this.verticalScrollBar.Value = view.Src.Row;
996             if (view.Src.X != this.horizontalScrollBar.Value)
997                 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
998         }
999
1000         void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
1001         {
1002             if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
1003             {
1004                 this.Refresh();
1005                 return;
1006             }
1007         }
1008
1009         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
1010         {
1011             if (this.horizontalScrollBar == null)
1012                 return;
1013             double toX;
1014             if (this.FlowDirection == FlowDirection.LeftToRight)
1015                 toX = this.horizontalScrollBar.Value;
1016             else
1017                 toX = -this.horizontalScrollBar.Value;
1018             this._Controller.Scroll(toX, this.View.Src.Row, false, false);
1019             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1020             this.Document.SelectGrippers.BottomRight.Enabled = false;
1021             this.Refresh();
1022         }
1023
1024         void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
1025         {
1026             if (this.verticalScrollBar == null)
1027                 return;
1028             int newRow = (int)this.verticalScrollBar.Value;
1029             if (newRow >= this.View.LayoutLines.Count)
1030                 return;
1031             this._Controller.Scroll(this.View.Src.X, newRow, false, false);
1032             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1033             this.Document.SelectGrippers.BottomRight.Enabled = false;
1034             this.Refresh();
1035         }
1036
1037         void Document_Update(object sender, DocumentUpdateEventArgs e)
1038         {
1039             if (this.textStore.IsLocked())
1040                 return;
1041             if (e.type == UpdateType.Replace)
1042                 TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);
1043             if(this.peer != null)
1044                 this.peer.OnNotifyTextChanged();
1045         }
1046
1047         void FooTextBox_Loaded(object sender, RoutedEventArgs e)
1048         {
1049             this.Focus(FocusState.Programmatic);
1050         }
1051
1052         void timer_Tick(object sender, object e)
1053         {
1054             bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding();
1055             if (updateAll)
1056                 this.Refresh();
1057         }
1058
1059         /// <inheritdoc/>
1060         public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
1061         {
1062             FooTextBox source = (FooTextBox)sender;
1063             if(e.Property.Equals(SelectedTextProperty) && !source.nowCaretMove)
1064                 source._Controller.SelectedText = source.SelectedText;
1065             if(e.Property.Equals(HilighterProperty))
1066                 source.View.Hilighter = source.Hilighter;
1067             if (e.Property.Equals(TextAntialiasModeProperty))
1068                 source.Render.TextAntialiasMode = source.TextAntialiasMode;
1069             if (e.Property.Equals(FoldingStrategyProperty))
1070                 source.View.LayoutLines.FoldingStrategy = source.FoldingStrategy;
1071             if (e.Property.Equals(IndentModeProperty))
1072                 source.Controller.IndentMode = source.IndentMode;
1073             if (e.Property.Equals(SelectionProperty) && !source.nowCaretMove)
1074                 source.Document.Select(source.Selection.Index,source.Selection.Length);
1075             if (e.Property.Equals(CaretPostionPropertyKey) && !source.nowCaretMove)
1076                 source.JumpCaret(source.CaretPostion.row, source.CaretPostion.col);
1077             if (e.Property.Equals(InsertModeProperty))
1078                 source.View.InsertMode = source.InsertMode;
1079             if (e.Property.Equals(TabCharsProperty))
1080                 source.Document.TabStops = source.TabChars;
1081             if (e.Property.Equals(RectSelectModeProperty))
1082                 source._Controller.RectSelection = source.RectSelectMode;
1083             if (e.Property.Equals(DrawCaretProperty))
1084                 source.View.HideCaret = !source.DrawCaret;
1085             if (e.Property.Equals(DrawCaretLineProperty))
1086                 source.View.HideLineMarker = !source.DrawCaretLine;
1087             if (e.Property.Equals(DrawLineNumberProperty))
1088                 source.Document.DrawLineNumber = source.DrawLineNumber;
1089             if(e.Property.Equals(MagnificationPowerPropertyKey))
1090                 source.Render.FontSize = source.FontSize * source.MagnificationPower;
1091             if (e.Property.Equals(FontFamilyProperty))
1092                 source.Render.FontFamily = source.FontFamily;
1093             if (e.Property.Equals(FontStyleProperty))
1094                 source.Render.FontStyle = source.FontStyle;
1095             if (e.Property.Equals(FontWeightProperty))
1096                 source.Render.FontWeigth = source.FontWeight;
1097             if (e.Property.Equals(FontSizeProperty))
1098                 source.Render.FontSize = source.FontSize;
1099             if (e.Property.Equals(ForegroundProperty))
1100                 source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground);
1101             if (e.Property.Equals(BackgroundProperty))
1102                 source.Render.Background = D2DRenderBase.ToColor4(source.Background);
1103             if (e.Property.Equals(ControlCharProperty))
1104                 source.Render.ControlChar = D2DRenderBase.ToColor4(source.ControlChar);
1105             if (e.Property.Equals(HilightProperty))
1106                 source.Render.Hilight = D2DRenderBase.ToColor4(source.Hilight);
1107             if (e.Property.Equals(Keyword1Property))
1108                 source.Render.Keyword1 = D2DRenderBase.ToColor4(source.Keyword1);
1109             if (e.Property.Equals(Keyword2Property))
1110                 source.Render.Keyword2 = D2DRenderBase.ToColor4(source.Keyword2);
1111             if (e.Property.Equals(CommentProperty))
1112                 source.Render.Comment = D2DRenderBase.ToColor4(source.Comment);
1113             if (e.Property.Equals(LiteralProperty))
1114                 source.Render.Literal = D2DRenderBase.ToColor4(source.Literal);
1115             if (e.Property.Equals(URLProperty))
1116                 source.Render.Url = D2DRenderBase.ToColor4(source.URL);
1117             if (e.Property.Equals(InsertCaretProperty))
1118                 source.Render.InsertCaret = D2DRenderBase.ToColor4(source.InsertCaret);
1119             if (e.Property.Equals(OverwriteCaretProperty))
1120                 source.Render.OverwriteCaret = D2DRenderBase.ToColor4(source.OverwriteCaret);
1121             if (e.Property.Equals(PaddingProperty))
1122                 source.View.Padding = new Padding((int)source.Padding.Left, (int)source.Padding.Top, (int)source.Padding.Right, (int)source.Padding.Bottom);
1123             if (e.Property.Equals(LineMarkerProperty))
1124                 source.Render.LineMarker = D2DRenderBase.ToColor4(source.LineMarker);
1125             if (e.Property.Equals(MarkURLProperty))
1126                 source.Document.UrlMark = source.MarkURL;
1127             if (e.Property.Equals(ShowFullSpaceProperty))
1128                 source.Render.ShowFullSpace = source.ShowFullSpace;
1129             if (e.Property.Equals(ShowHalfSpaceProperty))
1130                 source.Render.ShowHalfSpace = source.ShowHalfSpace;
1131             if (e.Property.Equals(ShowTabProperty))
1132                 source.Render.ShowTab = source.ShowTab;
1133             if (e.Property.Equals(ShowLineBreakProperty))
1134                 source.Render.ShowLineBreak = source.ShowLineBreak;
1135             if (e.Property.Equals(LineBreakProperty))
1136                 source.Document.LineBreak = source.LineBreakMethod;
1137             if (e.Property.Equals(LineBreakCharCountProperty))
1138                 source.Document.LineBreakCharCount = source.LineBreakCharCount;
1139             if (e.Property.Equals(UpdateAreaProperty))
1140                 source.Render.UpdateArea = D2DRenderBase.ToColor4(source.UpdateArea);
1141             if (e.Property.Equals(LineNumberProperty))
1142                 source.Render.LineNumber = D2DRenderBase.ToColor4(source.LineNumber);
1143             if (e.Property.Equals(FlowDirectionProperty))
1144             {
1145                 source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft;
1146                 if(source.horizontalScrollBar != null)
1147                     source.horizontalScrollBar.FlowDirection = source.FlowDirection;
1148             }
1149             if (e.Property.Equals(DrawRulerProperty))
1150             {
1151                 source.Document.HideRuler = !source.DrawRuler;
1152                 source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col);
1153             }
1154         }
1155         #endregion
1156
1157         #region event
1158         
1159         /// <summary>
1160         /// コンテキストメニューが表示されるときに呼び出されます
1161         /// </summary>
1162         public event EventHandler<FooContextMenuEventArgs> ContextMenuOpening;
1163
1164         #endregion
1165
1166         #region property
1167
1168         internal Controller Controller
1169         {
1170             get
1171             {
1172                 return this._Controller;
1173             }
1174         }
1175
1176         /// <summary>
1177         /// 文字列の描写に使用されるアンチエイリアシング モードを表します
1178         /// </summary>
1179         public TextAntialiasMode TextAntialiasMode
1180         {
1181             get { return (TextAntialiasMode)GetValue(TextAntialiasModeProperty); }
1182             set { SetValue(TextAntialiasModeProperty, value); }
1183         }
1184
1185         /// <summary>
1186         /// TextAntialiasModeの依存プロパティを表す
1187         /// </summary>
1188         public static readonly DependencyProperty TextAntialiasModeProperty =
1189             DependencyProperty.Register("TextAntialiasMode", typeof(TextAntialiasMode), typeof(FooTextBox), new PropertyMetadata(TextAntialiasMode.Default));
1190
1191         /// <summary>
1192         /// シンタックスハイライターを表す
1193         /// </summary>
1194         public IHilighter Hilighter
1195         {
1196             get { return (IHilighter)GetValue(HilighterProperty); }
1197             set { SetValue(HilighterProperty, value); }
1198         }
1199
1200         /// <summary>
1201         /// Hilighterの依存プロパティを表す
1202         /// </summary>
1203         public static readonly DependencyProperty HilighterProperty =
1204             DependencyProperty.Register("Hilighter", typeof(IHilighter), typeof(FooTextBox), new PropertyMetadata(null));
1205
1206         /// <summary>
1207         /// フォールティングを作成するインターフェイスを表す
1208         /// </summary>
1209         public IFoldingStrategy FoldingStrategy
1210         {
1211             get { return (IFoldingStrategy)GetValue(FoldingStrategyProperty); }
1212             set { SetValue(FoldingStrategyProperty, value); }
1213         }
1214
1215         /// <summary>
1216         /// FoldingStrategyの依存プロパティ
1217         /// </summary>
1218         public static readonly DependencyProperty FoldingStrategyProperty =
1219             DependencyProperty.Register("FoldingStrategy", typeof(IFoldingStrategy), typeof(FooTextBox), new PropertyMetadata(null));
1220
1221         /// <summary>
1222         /// マーカーパターンセットを表す
1223         /// </summary>
1224         public MarkerPatternSet MarkerPatternSet
1225         {
1226             get
1227             {
1228                 return this.Document.MarkerPatternSet;
1229             }
1230         }
1231
1232         /// <summary>
1233         /// ドキュメントを表す
1234         /// </summary>
1235         public Document Document
1236         {
1237             get
1238             {
1239                 return this._Document;
1240             }
1241             set
1242             {
1243                 Document old_doc = this._Document;
1244                 int oldLength = 0;
1245                 if (this._Document != null)
1246                 {
1247                     old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
1248                     oldLength = old_doc.Length;
1249                 }
1250
1251                 this._Document = value;
1252                 this._Document.LayoutLines.Render = this.Render;
1253                 this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
1254                 //初期化が終わっていればすべて存在する
1255                 if (this.Controller != null && this.View != null && this.textStore != null)
1256                 {
1257                     this.Controller.Document = value;
1258                     this.View.Document = value;
1259                     this.Controller.AdjustCaret();
1260                     this.textStore.NotifyTextChanged(oldLength, value.Length);
1261
1262                     //依存プロパティとドキュメント内容が食い違っているので再設定する
1263                     this.ShowFullSpace = value.ShowFullSpace;
1264                     this.ShowHalfSpace = value.ShowHalfSpace;
1265                     this.ShowLineBreak = value.ShowLineBreak;
1266                     this.ShowTab = value.ShowTab;
1267                     this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
1268                     this.IndentMode = value.IndentMode;
1269                     this.DrawCaretLine = !value.HideLineMarker;
1270                     this.InsertMode = value.InsertMode;
1271                     this.DrawRuler = !value.HideRuler;
1272                     this.DrawLineNumber = value.DrawLineNumber;
1273                     this.MarkURL = value.UrlMark;
1274                     this.LineBreakMethod = value.LineBreak;
1275                     this.LineBreakCharCount = value.LineBreakCharCount;
1276                     this.TabChars = value.TabStops;
1277
1278                     this.Refresh();
1279                 }
1280             }
1281         }
1282
1283         /// <summary>
1284         /// レイアウト行を表す
1285         /// </summary>
1286         public LineToIndexTable LayoutLineCollection
1287         {
1288             get { return this.View.LayoutLines; }
1289         }
1290
1291         /// <summary>
1292         /// 選択中の文字列を表す
1293         /// </summary>
1294         public string SelectedText
1295         {
1296             get { return (string)GetValue(SelectedTextProperty); }
1297             set { SetValue(SelectedTextProperty, value); }
1298         }
1299
1300         /// <summary>
1301         /// SelectedTextの依存プロパティを表す
1302         /// </summary>
1303         public static readonly DependencyProperty SelectedTextProperty =
1304             DependencyProperty.Register("SelectedText", typeof(string), typeof(FooTextBox), new PropertyMetadata(null));
1305
1306         /// <summary>
1307         /// インデントの方法を表す
1308         /// </summary>
1309         public IndentMode IndentMode
1310         {
1311             get { return (IndentMode)GetValue(IndentModeProperty); }
1312             set { SetValue(IndentModeProperty, value); }
1313         }
1314
1315         /// <summary>
1316         /// IndentModeの依存プロパティを表す
1317         /// </summary>
1318         public static readonly DependencyProperty IndentModeProperty =
1319             DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab,OnPropertyChanged));
1320
1321         /// <summary>
1322         /// 選択範囲を表す
1323         /// </summary>
1324         /// <remarks>
1325         /// Lengthが0の場合はキャレット位置を表します。
1326         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
1327         /// </remarks>
1328         public TextRange Selection
1329         {
1330             get { return (TextRange)GetValue(SelectionProperty); }
1331             set { SetValue(SelectionProperty, value); }
1332         }
1333
1334         /// <summary>
1335         /// Selectionの依存プロパティを表す
1336         /// </summary>
1337         public static readonly DependencyProperty SelectionProperty =
1338             DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(0));
1339
1340         /// <summary>
1341         /// 拡大率を表す
1342         /// </summary>
1343         public double MagnificationPower
1344         {
1345             get { return (double)GetValue(MagnificationPowerPropertyKey); }
1346             set { SetValue(MagnificationPowerPropertyKey, value); }
1347         }
1348
1349         /// <summary>
1350         /// 拡大率を表す依存プロパティ
1351         /// </summary>
1352         public static readonly DependencyProperty MagnificationPowerPropertyKey =
1353             DependencyProperty.Register("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0, OnPropertyChanged));
1354
1355         /// <summary>
1356         /// キャレット位置を表す
1357         /// </summary>
1358         public TextPoint CaretPostion
1359         {
1360             get { return (TextPoint)GetValue(CaretPostionPropertyKey); }
1361             set { SetValue(CaretPostionPropertyKey, value); }
1362         }
1363
1364         static readonly DependencyProperty CaretPostionPropertyKey =
1365             DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(new TextPoint(), OnPropertyChanged));
1366
1367         /// <summary>
1368         /// レタリング方向を表す
1369         /// </summary>
1370         public new FlowDirection FlowDirection
1371         {
1372             get { return (FlowDirection)GetValue(FlowDirectionProperty); }
1373             set { SetValue(FlowDirectionProperty, value); }
1374         }
1375
1376         /// <summary>
1377         /// レタリング方向を表す。これは依存プロパティです
1378         /// </summary>
1379         public new static readonly DependencyProperty FlowDirectionProperty =
1380             DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight,OnPropertyChanged));
1381
1382         /// <summary>
1383         /// フォントファミリーを表す
1384         /// </summary>
1385         public new FontFamily FontFamily
1386         {
1387             get { return (FontFamily)GetValue(FontFamilyProperty); }
1388             set { SetValue(FontFamilyProperty, value); }
1389         }
1390
1391         /// <summary>
1392         /// FontFamilyの依存プロパティを表す
1393         /// </summary>
1394         public new static readonly DependencyProperty FontFamilyProperty =
1395             DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(FooTextBox), new PropertyMetadata(new FontFamily("Cambria"), OnPropertyChanged));
1396
1397         /// <summary>
1398         /// フォントサイズを表す
1399         /// </summary>
1400         public new double FontSize
1401         {
1402             get { return (double)GetValue(FontSizeProperty); }
1403             set { SetValue(FontSizeProperty, value); }
1404         }
1405
1406         /// <summary>
1407         /// FontSizeの依存プロパティを表す
1408         /// </summary>
1409         public new static readonly DependencyProperty FontSizeProperty =
1410             DependencyProperty.Register("FontSize", typeof(double), typeof(FooTextBox), new PropertyMetadata(12.0,OnPropertyChanged));
1411
1412         /// <summary>
1413         /// フォントスタイルを表す
1414         /// </summary>
1415         public new FontStyle FontStyle
1416         {
1417             get { return (FontStyle)GetValue(FontStyleProperty); }
1418             set { SetValue(FontStyleProperty, value); }
1419         }
1420
1421         /// <summary>
1422         /// FontStyleの依存プロパティを表す
1423         /// </summary>
1424         public new static readonly DependencyProperty FontStyleProperty =
1425             DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(FooTextBox), new PropertyMetadata(FontStyle.Normal,OnPropertyChanged));
1426
1427         /// <summary>
1428         /// フォントの幅を表す
1429         /// </summary>
1430         public new FontWeight FontWeight
1431         {
1432             get { return (FontWeight)GetValue(FontWeightProperty); }
1433             set { SetValue(FontWeightProperty, value); }
1434         }
1435
1436         /// <summary>
1437         /// FontWeigthの依存プロパティを表す
1438         /// </summary>
1439         public new static readonly DependencyProperty FontWeightProperty =
1440             DependencyProperty.Register("FontWeigth", typeof(FontWeight), typeof(FooTextBox), new PropertyMetadata(FontWeights.Normal,OnPropertyChanged));
1441
1442         /// <summary>
1443         /// デフォルトの文字色を表す。これは依存プロパティです
1444         /// </summary>
1445         public new Windows.UI.Color Foreground
1446         {
1447             get { return (Windows.UI.Color)GetValue(ForegroundProperty); }
1448             set { SetValue(ForegroundProperty, value); }
1449         }
1450
1451         /// <summary>
1452         /// Foregroundの依存プロパティを表す
1453         /// </summary>
1454         public new static readonly DependencyProperty ForegroundProperty =
1455             DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1456
1457         /// <summary>
1458         /// 背景色を表す。これは依存プロパティです
1459         /// </summary>
1460         public new Windows.UI.Color Background
1461         {
1462             get { return (Windows.UI.Color)GetValue(BackgroundProperty); }
1463             set { SetValue(BackgroundProperty, value); }
1464         }
1465
1466         /// <summary>
1467         /// Backgroundの依存プロパティを表す
1468         /// </summary>
1469         public new static readonly DependencyProperty BackgroundProperty =
1470             DependencyProperty.Register("Background", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
1471
1472         /// <summary>
1473         /// コントロールコードの文字色を表す。これは依存プロパティです
1474         /// </summary>
1475         public Windows.UI.Color ControlChar
1476         {
1477             get { return (Windows.UI.Color)GetValue(ControlCharProperty); }
1478             set { SetValue(ControlCharProperty, value); }
1479         }
1480
1481         /// <summary>
1482         /// ControlCharの依存プロパティを表す
1483         /// </summary>
1484         public static readonly DependencyProperty ControlCharProperty =
1485             DependencyProperty.Register("ControlChar", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1486
1487         /// <summary>
1488         /// 選択時の背景色を表す。これは依存プロパティです
1489         /// </summary>
1490         public Windows.UI.Color Hilight
1491         {
1492             get { return (Windows.UI.Color)GetValue(HilightProperty); }
1493             set { SetValue(HilightProperty, value); }
1494         }
1495
1496         /// <summary>
1497         /// Hilightの依存プロパティを表す
1498         /// </summary>
1499         public static readonly DependencyProperty HilightProperty =
1500             DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DeepSkyBlue, OnPropertyChanged));
1501
1502         /// <summary>
1503         /// キーワード1の文字色を表す。これは依存プロパティです
1504         /// </summary>
1505         public Windows.UI.Color Keyword1
1506         {
1507             get { return (Windows.UI.Color)GetValue(Keyword1Property); }
1508             set { SetValue(Keyword1Property, value); }
1509         }
1510
1511         /// <summary>
1512         /// Keyword1の依存プロパティを表す
1513         /// </summary>
1514         public static readonly DependencyProperty Keyword1Property =
1515             DependencyProperty.Register("Keyword1", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1516
1517         /// <summary>
1518         /// キーワード2の文字色を表す。これは依存プロパティです
1519         /// </summary>
1520         public Windows.UI.Color Keyword2
1521         {
1522             get { return (Windows.UI.Color)GetValue(Keyword2Property); }
1523             set { SetValue(Keyword2Property, value); }
1524         }
1525
1526         /// <summary>
1527         /// Keyword2の依存プロパティを表す
1528         /// </summary>
1529         public static readonly DependencyProperty Keyword2Property =
1530             DependencyProperty.Register("Keyword2", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DarkCyan, OnPropertyChanged));
1531
1532         /// <summary>
1533         /// コメントの文字色を表す。これは依存プロパティです
1534         /// </summary>
1535         public Windows.UI.Color Comment
1536         {
1537             get { return (Windows.UI.Color)GetValue(CommentProperty); }
1538             set { SetValue(CommentProperty, value); }
1539         }
1540
1541         /// <summary>
1542         /// Commentの依存プロパティを表す
1543         /// </summary>
1544         public static readonly DependencyProperty CommentProperty =
1545             DependencyProperty.Register("Comment", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Green, OnPropertyChanged));
1546
1547         /// <summary>
1548         /// 文字リテラルの文字色を表す。これは依存プロパティです
1549         /// </summary>
1550         public Windows.UI.Color Literal
1551         {
1552             get { return (Windows.UI.Color)GetValue(LiteralProperty); }
1553             set { SetValue(LiteralProperty, value); }
1554         }
1555
1556         /// <summary>
1557         /// Literalの依存プロパティを表す
1558         /// </summary>
1559         public static readonly DependencyProperty LiteralProperty =
1560             DependencyProperty.Register("Literal", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Brown, OnPropertyChanged));
1561
1562         /// <summary>
1563         /// URLの文字色を表す。これは依存プロパティです
1564         /// </summary>
1565         public Windows.UI.Color URL
1566         {
1567             get { return (Windows.UI.Color)GetValue(URLProperty); }
1568             set { SetValue(URLProperty, value); }
1569         }
1570
1571         /// <summary>
1572         /// URLの依存プロパティを表す
1573         /// </summary>
1574         public static readonly DependencyProperty URLProperty =
1575             DependencyProperty.Register("URL", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1576
1577         /// <summary>
1578         /// 行更新フラグの色を表す
1579         /// </summary>
1580         public Windows.UI.Color UpdateArea
1581         {
1582             get { return (Windows.UI.Color)GetValue(UpdateAreaProperty); }
1583             set { SetValue(UpdateAreaProperty, value); }
1584         }
1585
1586         /// <summary>
1587         /// UpdateAreaの依存プロパティを表す
1588         /// </summary>
1589         public static readonly DependencyProperty UpdateAreaProperty =
1590             DependencyProperty.Register("UpdateArea", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));
1591
1592         /// <summary>
1593         /// ラインマーカーの色を表す
1594         /// </summary>
1595         public Windows.UI.Color LineMarker
1596         {
1597             get { return (Windows.UI.Color)GetValue(LineMarkerProperty); }
1598             set { SetValue(LineMarkerProperty, value); }
1599         }
1600
1601         /// <summary>
1602         /// LineMarkerの依存プロパティを表す
1603         /// </summary>
1604         public static readonly DependencyProperty LineMarkerProperty =
1605             DependencyProperty.Register("LineMarker", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1606
1607         /// <summary>
1608         /// 挿入モード時のキャレットの色を表す
1609         /// </summary>
1610         public Windows.UI.Color InsertCaret
1611         {
1612             get { return (Windows.UI.Color)GetValue(InsertCaretProperty); }
1613             set { SetValue(InsertCaretProperty, value); }
1614         }
1615
1616         /// <summary>
1617         /// InsertCaretの依存プロパティを表す
1618         /// </summary>
1619         public static readonly DependencyProperty InsertCaretProperty =
1620             DependencyProperty.Register("InsertCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1621
1622         /// <summary>
1623         /// 上書きモード時のキャレット職を表す
1624         /// </summary>
1625         public Windows.UI.Color OverwriteCaret
1626         {
1627             get { return (Windows.UI.Color)GetValue(OverwriteCaretProperty); }
1628             set { SetValue(OverwriteCaretProperty, value); }
1629         }
1630
1631         /// <summary>
1632         /// OverwriteCaretの依存プロパティを表す
1633         /// </summary>
1634         public static readonly DependencyProperty OverwriteCaretProperty =
1635             DependencyProperty.Register("OverwriteCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1636
1637         /// <summary>
1638         /// 行番号の色を表す
1639         /// </summary>
1640         public Windows.UI.Color LineNumber
1641         {
1642             get { return (Windows.UI.Color)GetValue(LineNumberProperty); }
1643             set { SetValue(LineNumberProperty, value); }
1644         }
1645
1646         /// <summary>
1647         /// Using a DependencyProperty as the backing store for LineNumber.  This enables animation, styling, binding, etc...
1648         /// </summary>
1649         public static readonly DependencyProperty LineNumberProperty =
1650             DependencyProperty.Register("LineNumber", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray,OnPropertyChanged));
1651
1652         /// <summary>
1653         /// 余白を表す
1654         /// </summary>
1655         public new Thickness Padding
1656         {
1657             get { return (Thickness)GetValue(PaddingProperty); }
1658             set { SetValue(PaddingProperty, value); }
1659         }
1660
1661         /// <summary>
1662         /// Paddingの依存プロパティを表す
1663         /// </summary>
1664         public new static readonly DependencyProperty PaddingProperty =
1665             DependencyProperty.Register("Padding", typeof(Thickness), typeof(FooTextBox), new PropertyMetadata(new Thickness(),OnPropertyChanged));        
1666
1667         /// <summary>
1668         /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
1669         /// </summary>
1670         public bool InsertMode
1671         {
1672             get { return (bool)GetValue(InsertModeProperty); }
1673             set { SetValue(InsertModeProperty, value); }
1674         }
1675
1676         /// <summary>
1677         /// InsertModeの依存プロパティを表す
1678         /// </summary>
1679         public static readonly DependencyProperty InsertModeProperty =
1680             DependencyProperty.Register("InsertMode",
1681             typeof(bool),
1682             typeof(FooTextBox),
1683             new PropertyMetadata(true, OnPropertyChanged));
1684
1685         /// <summary>
1686         /// タブの文字数を表す。これは依存プロパティです
1687         /// </summary>
1688         public int TabChars
1689         {
1690             get { return (int)GetValue(TabCharsProperty); }
1691             set { SetValue(TabCharsProperty, value); }
1692         }
1693
1694         /// <summary>
1695         /// TabCharsの依存プロパティを表す
1696         /// </summary>
1697         public static readonly DependencyProperty TabCharsProperty =
1698             DependencyProperty.Register("TabChars",
1699             typeof(int),
1700             typeof(FooTextBox),
1701             new PropertyMetadata(4, OnPropertyChanged));
1702
1703         /// <summary>
1704         /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
1705         /// </summary>
1706         public bool RectSelectMode
1707         {
1708             get { return (bool)GetValue(RectSelectModeProperty); }
1709             set { SetValue(RectSelectModeProperty, value); }
1710         }
1711
1712         /// <summary>
1713         /// RectSelectModeの依存プロパティを表す
1714         /// </summary>
1715         public static readonly DependencyProperty RectSelectModeProperty =
1716             DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1717
1718         /// <summary>
1719         /// 折り返しの方法を指定する
1720         /// </summary>
1721         /// <remarks>
1722         /// 変更した場合、レイアウトの再構築を行う必要があります
1723         /// </remarks>
1724         public LineBreakMethod LineBreakMethod
1725         {
1726             get { return (LineBreakMethod)GetValue(LineBreakProperty); }
1727             set { SetValue(LineBreakProperty, value); }
1728         }
1729
1730         /// <summary>
1731         /// LineBreakMethodの依存プロパティを表す
1732         /// </summary>
1733         public static readonly DependencyProperty LineBreakProperty =
1734             DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None, OnPropertyChanged));
1735
1736
1737         /// <summary>
1738         /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
1739         /// </summary>
1740         /// <remarks>
1741         /// 変更した場合、レイアウトの再構築を行う必要があります
1742         /// </remarks>
1743         public int LineBreakCharCount
1744         {
1745             get { return (int)GetValue(LineBreakCharCountProperty); }
1746             set { SetValue(LineBreakCharCountProperty, value); }
1747         }
1748
1749         /// <summary>
1750         /// LineBreakCharCountの依存プロパティを表す
1751         /// </summary>
1752         public static readonly DependencyProperty LineBreakCharCountProperty =
1753             DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));        
1754
1755         /// <summary>
1756         /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1757         /// </summary>
1758         public bool DrawCaret
1759         {
1760             get { return (bool)GetValue(DrawCaretProperty); }
1761             set { SetValue(DrawCaretProperty, value); }
1762         }
1763
1764         /// <summary>
1765         /// DrawCaretの依存プロパティを表す
1766         /// </summary>
1767         public static readonly DependencyProperty DrawCaretProperty =
1768             DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new PropertyMetadata(true, OnPropertyChanged));
1769
1770
1771         /// <summary>
1772         /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1773         /// </summary>
1774         public bool DrawCaretLine
1775         {
1776             get { return (bool)GetValue(DrawCaretLineProperty); }
1777             set { SetValue(DrawCaretLineProperty, value); }
1778         }
1779
1780         /// <summary>
1781         /// DrawCaretLineの依存プロパティを表す
1782         /// </summary>
1783         public static readonly DependencyProperty DrawCaretLineProperty =
1784             DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1785
1786         /// <summary>
1787         /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
1788         /// </summary>
1789         public bool DrawLineNumber
1790         {
1791             get { return (bool)GetValue(DrawLineNumberProperty); }
1792             set { SetValue(DrawLineNumberProperty, value); }
1793         }
1794
1795         /// <summary>
1796         /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
1797         /// </summary>
1798         public bool DrawRuler
1799         {
1800             get { return (bool)GetValue(DrawRulerProperty); }
1801             set { SetValue(DrawRulerProperty, value); }
1802         }
1803
1804         /// <summary>
1805         /// DrawRulerの依存プロパティを表す
1806         /// </summary>
1807         public static readonly DependencyProperty DrawRulerProperty =
1808             DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1809
1810
1811         /// <summary>
1812         /// DrawLineNumberの依存プロパティを表す
1813         /// </summary>
1814         public static readonly DependencyProperty DrawLineNumberProperty =
1815             DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1816
1817         /// <summary>
1818         /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
1819         /// </summary>
1820         public bool MarkURL
1821         {
1822             get { return (bool)GetValue(MarkURLProperty); }
1823             set { SetValue(MarkURLProperty, value); }
1824         }
1825
1826         /// <summary>
1827         /// MarkURLの依存プロパティを表す
1828         /// </summary>
1829         public static readonly DependencyProperty MarkURLProperty =
1830             DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1831
1832         /// <summary>
1833         /// 全角スペースを表示するなら真。そうでないなら偽
1834         /// </summary>
1835         public bool ShowFullSpace
1836         {
1837             get { return (bool)GetValue(ShowFullSpaceProperty); }
1838             set { SetValue(ShowFullSpaceProperty, value); }
1839         }
1840
1841         /// <summary>
1842         /// ShowFullSpaceの依存プロパティを表す
1843         /// </summary>
1844         public static readonly DependencyProperty ShowFullSpaceProperty =
1845             DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1846
1847         /// <summary>
1848         /// 半角スペースを表示するなら真。そうでないなら偽
1849         /// </summary>
1850         public bool ShowHalfSpace
1851         {
1852             get { return (bool)GetValue(ShowHalfSpaceProperty); }
1853             set { SetValue(ShowHalfSpaceProperty, value); }
1854         }
1855
1856         /// <summary>
1857         /// ShowHalfSpaceの依存プロパティを表す
1858         /// </summary>
1859         public static readonly DependencyProperty ShowHalfSpaceProperty =
1860             DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1861
1862         /// <summary>
1863         /// タブを表示するなら真。そうでないなら偽
1864         /// </summary>
1865         public bool ShowTab
1866         {
1867             get { return (bool)GetValue(ShowTabProperty); }
1868             set { SetValue(ShowTabProperty, value); }
1869         }
1870
1871         /// <summary>
1872         /// ShowTabの依存プロパティを表す
1873         /// </summary>
1874         public static readonly DependencyProperty ShowTabProperty =
1875             DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1876
1877         /// <summary>
1878         /// 改行マークを表示するなら真。そうでないなら偽
1879         /// </summary>
1880         public bool ShowLineBreak
1881         {
1882             get { return (bool)GetValue(ShowLineBreakProperty); }
1883             set { SetValue(ShowLineBreakProperty, value); }
1884         }
1885
1886         /// <summary>
1887         /// ShowLineBreakの依存プロパティを表す
1888         /// </summary>
1889         public static readonly DependencyProperty ShowLineBreakProperty =
1890             DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false,OnPropertyChanged));
1891
1892         
1893         #endregion
1894
1895     }
1896     /// <summary>
1897     /// コンテキストメニューのイベントデーターを表す
1898     /// </summary>
1899     public class FooContextMenuEventArgs
1900     {
1901         /// <summary>
1902         /// 処理済みなら真。そうでないなら偽
1903         /// </summary>
1904         public bool Handled = false;
1905         /// <summary>
1906         /// コンテキストメニューを表示すべき座標を表す
1907         /// </summary>
1908         public Windows.Foundation.Point Postion;
1909         /// <summary>
1910         /// コンストラクター
1911         /// </summary>
1912         /// <param name="pos"></param>
1913         public FooContextMenuEventArgs(Windows.Foundation.Point pos)
1914         {
1915             this.Postion = pos;
1916         }
1917     }
1918 }