OSDN Git Service

ebb25ea1c0fe89480777c99ac6be9cad74d77b42
[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
54         /// <summary>
55         /// コンストラクター
56         /// </summary>
57         public FooTextBox()
58         {
59             this.DefaultStyleKey = typeof(FooTextBox);
60
61             this.textStore = new TextStore2();
62             this.textStore.IsLoading += textStore_IsLoading;
63             this.textStore.IsReadOnly += textStore_IsReadOnly;
64             this.textStore.GetStringLength += () => this.Document.Length;
65             this.textStore.GetString += _textStore_GetString;
66             this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex;
67             this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex;
68             this.textStore.InsertAtSelection += _textStore_InsertAtSelection;
69             this.textStore.GetScreenExtent += _textStore_GetScreenExtent;
70             this.textStore.GetStringExtent += _textStore_GetStringExtent;
71             this.textStore.CompositionStarted += textStore_CompositionStarted;
72             this.textStore.CompositionUpdated += textStore_CompositionUpdated;
73             this.textStore.CompositionEnded += textStore_CompositionEnded;
74
75             this.rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
76             this.rectangle.Margin = this.Padding;
77             this.Render = new D2DRender(this,this.rectangle,this.textStore);
78
79             this.Document = new Document();
80             this.Document.LayoutLines.Render = this.Render;
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._Controller.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._Controller.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._Controller.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             //マウスでは慣性移動自体必要じゃない
605             this.gestureRecongnizer.AutoProcessInertia = e.Pointer.PointerDeviceType != PointerDeviceType.Mouse;
606
607             this.CapturePointer(e.Pointer);
608             this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this));
609             e.Handled = true;
610         }
611
612         /// <inheritdoc/>
613         protected override void OnPointerMoved(PointerRoutedEventArgs e)
614         {
615             //マウスでは慣性移動自体必要じゃない
616             this.gestureRecongnizer.AutoProcessInertia = e.Pointer.PointerDeviceType != PointerDeviceType.Mouse;
617
618             this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
619             e.Handled = true;
620
621             if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
622             {
623                 Point p = e.GetCurrentPoint(this).Position;
624                 if (this.View.HitTextArea(p.X, p.Y))
625                 {
626                     TextPoint tp = this.View.GetTextPointFromPostion(p);
627                     if (this._Controller.IsMarker(tp, HilightType.Url))
628                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Hand, 101);
629                     else
630                         Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.IBeam, 101);
631                 }
632                 else
633                 {
634                     Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 101);
635                 }
636             }
637         }
638
639         /// <inheritdoc/>
640         protected override void OnPointerReleased(PointerRoutedEventArgs e)
641         {
642             this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this));
643             this.ReleasePointerCapture(e.Pointer);
644             e.Handled = true;
645         }
646
647         /// <inheritdoc/>
648         protected override void OnPointerCanceled(PointerRoutedEventArgs e)
649         {
650             this.gestureRecongnizer.CompleteGesture();
651             this.ReleasePointerCapture(e.Pointer);
652             e.Handled = true;
653         }
654
655         /// <inheritdoc/>
656         protected override void OnPointerCaptureLost(PointerRoutedEventArgs e)
657         {
658             this.gestureRecongnizer.CompleteGesture();
659             this.ReleasePointerCapture(e.Pointer);
660             e.Handled = true;
661         }
662
663         /// <inheritdoc/>
664         protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
665         {
666             //マウスでは慣性移動自体必要じゃない
667             this.gestureRecongnizer.AutoProcessInertia = e.Pointer.PointerDeviceType != PointerDeviceType.Mouse;
668
669             bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
670                 Windows.System.VirtualKeyModifiers.Shift;
671             bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
672                 Windows.System.VirtualKeyModifiers.Control;
673             this.gestureRecongnizer.ProcessMouseWheelEvent(e.GetCurrentPoint(this), shift, ctrl);
674             e.Handled = true;
675         }
676
677         void CoreWindow_CharacterReceived(CoreWindow sender, CharacterReceivedEventArgs args)
678         {
679             if (this.FocusState == FocusState.Unfocused || !this.IsEnabled)
680                 return;
681             if (args.KeyCode >= 00 && args.KeyCode <= 0x1f)
682                 return;
683             this._Controller.DoInputString(Char.ConvertFromUtf32((int)args.KeyCode));
684             this.Refresh();
685         }
686
687         bool textStore_IsReadOnly()
688         {
689             return false;
690         }
691
692         bool textStore_IsLoading()
693         {
694             return false;
695         }
696
697         void textStore_CompositionEnded()
698         {
699             TextStoreHelper.EndCompostion(this.Document);
700             this.Refresh();
701         }
702
703         void textStore_CompositionUpdated(int start, int end)
704         {
705             if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end))
706                 this.Refresh();
707         }
708         bool textStore_CompositionStarted()
709         {
710             return TextStoreHelper.StartCompstion(this.Document);
711         }
712
713         string _textStore_GetString(int start, int length)
714         {
715             return this.Document.ToString(start, length);
716         }
717
718         void _textStore_GetStringExtent(
719             int i_startIndex,
720             int i_endIndex,
721             out POINT o_topLeft,
722             out POINT o_bottomRight
723         )
724         {
725             Point startPos, endPos;
726             TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos);
727
728             float dpi;
729             this.Render.GetDpi(out dpi, out dpi);
730             double scale = dpi / 96.0;
731
732             var gt = this.TransformToVisual(Window.Current.Content);
733             startPos = gt.TransformPoint(startPos.Scale(scale));
734             endPos = gt.TransformPoint(endPos.Scale(scale));
735
736             o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);
737             o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);
738         }
739
740         void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)
741         {
742             var pointTopLeft = new Point(0, 0);
743             var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
744
745             var gt = this.TransformToVisual(Window.Current.Content);
746             pointTopLeft = gt.TransformPoint(pointTopLeft);
747             pointBottomRight = gt.TransformPoint(pointBottomRight);
748
749             o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);
750             o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);
751         }
752
753         void _textStore_GetSelectionIndex(out int o_startIndex, out int o_endIndex)
754         {
755             TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out o_startIndex, out o_endIndex);
756         }
757
758         void _textStore_SetSelectionIndex(int i_startIndex, int i_endIndex)
759         {
760             TextStoreHelper.SetSelectionIndex(this._Controller, this.View, i_startIndex, i_endIndex);
761             this.Refresh();
762         }
763
764         void _textStore_InsertAtSelection(string i_value,ref int o_stratIndex,ref int o_endIndex)
765         {
766             TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);
767             this.Refresh();
768         }
769
770         void Controller_SelectionChanged(object sender, EventArgs e)
771         {
772             //こうしないと選択できなくなってしまう
773             this.nowCaretMove = true;
774             SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
775             SetValue(CaretPostionPropertyKey, this.Document.CaretPostion);
776             this.nowCaretMove = false;
777             this.Document.SelectGrippers.BottomLeft.MoveByIndex(this.View, this.Controller.SelectionStart);
778             this.Document.SelectGrippers.BottomRight.MoveByIndex(this.View, this.Controller.SelectionStart + this.Controller.SelectionLength);
779             if (this.textStore.IsLocked() == false)
780                 this.textStore.NotifySelectionChanged();
781         }
782
783         private void gestureRecongnizer_ManipulationInertiaStarting(GestureRecognizer sender, ManipulationInertiaStartingEventArgs e)
784         {
785             //sender.InertiaTranslationDeceleration = 0.001f;
786             //sender.InertiaExpansionDeceleration = 100.0f * 96.0f / 1000.0f;
787             //sender.InertiaRotationDeceleration = 720.0f / (1000.0f * 1000.0f);
788         }
789
790         Gripper hittedGripper;
791         void gestureRecongnizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs e)
792         {
793             //Updateedの段階でヒットテストしてしまうとグリッパーを触ってもヒットしないことがある
794             this.hittedGripper = this.View.HitGripperFromPoint(e.Position);
795         }
796
797         const int WheelNoti = 120;
798         const int WheelScrollLines = 3;
799         double TotalWheelCount = 0;
800
801         void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e)
802         {
803             if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper))
804             {
805                 if (this.peer != null)
806                     this.peer.OnNotifyCaretChanged();
807                 this.Refresh();                
808                 return;
809             }
810
811             if (e.Delta.Scale < 1)
812             {
813                 double newSize = this.Render.FontSize - 1;
814                 if (newSize < 1)
815                     newSize = 1;
816                 this.Render.FontSize = newSize;
817                 this.Refresh();
818                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
819                 return;
820             }
821             
822             if (e.Delta.Scale > 1)
823             {
824                 double newSize = this.Render.FontSize + 1;
825                 if (newSize > 72)
826                     newSize = 72;
827                 this.Render.FontSize = newSize;
828                 this.Refresh();
829                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
830                 return;
831             }
832             
833             Point translation = e.Delta.Translation;
834
835             //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい
836             if (Math.Abs(e.Cumulative.Translation.X) < Math.Abs(e.Cumulative.Translation.Y))
837             {
838                 int scrollCount = 0;
839                 if (e.PointerDeviceType == PointerDeviceType.Mouse) {
840                     //テキストボックスはWheelNotiごとにWheelScrollLinesずつスクロールするらしい
841                     scrollCount = (int)Math.Abs(this.TotalWheelCount / WheelNoti * WheelScrollLines);
842                     if (scrollCount < 1)
843                         scrollCount = 1;
844                     else if (scrollCount > WheelScrollLines)
845                         scrollCount = WheelScrollLines;
846                     if (this.TotalWheelCount >= WheelNoti)  //0にすると違和感を感じる
847                         this.TotalWheelCount = this.TotalWheelCount % WheelNoti;
848                     this.TotalWheelCount += Math.Abs(translation.Y);
849                 }
850                 else
851                 {
852                     scrollCount = (int)Math.Abs(translation.Y + 0.5);
853                 }
854
855                 if (translation.Y > 0)
856                     this._Controller.Scroll(ScrollDirection.Up, scrollCount, false, false);
857                 else
858                     this._Controller.Scroll(ScrollDirection.Down, scrollCount, false, false);
859                 this.Document.SelectGrippers.BottomLeft.Enabled = false;
860                 this.Document.SelectGrippers.BottomRight.Enabled = false;
861                 this.Refresh();
862                 return;
863             }
864
865             int deltax = (int)Math.Abs(Math.Ceiling(translation.X));
866             if (deltax != 0)
867             {
868                 if (translation.X < 0)
869                     this._Controller.Scroll(ScrollDirection.Left, deltax, false, false);
870                 else
871                     this._Controller.Scroll(ScrollDirection.Right, deltax, false, false);
872                 this.Document.SelectGrippers.BottomLeft.Enabled = false;
873                 this.Document.SelectGrippers.BottomRight.Enabled = false;
874                 this.Refresh();
875             }
876         }
877
878         void gestureRecongnizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs e)
879         {
880         }
881
882         async void gestureRecongnizer_RightTapped(GestureRecognizer sender, RightTappedEventArgs e)
883         {
884             ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.Metro/Resources");
885             ResourceContext context = ResourceContext.GetForCurrentView();
886             if (this.View.HitTextArea(e.Position.X, e.Position.Y))
887             {
888                 FooContextMenuEventArgs args = new FooContextMenuEventArgs(e.Position);
889                 if (this.ContextMenuOpening != null)
890                     this.ContextMenuOpening(this, args);
891                 if (!args.Handled)
892                 {
893                     PopupMenu ContextMenu = new PopupMenu();
894                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CopyMenuName", context).ValueAsString, (command) =>
895                     {
896                         this.CopyCommand();
897                     }));
898                     ContextMenu.Commands.Add(new UICommand(map.GetValue("CutMenuName", context).ValueAsString, (command) =>
899                     {
900                         this.CutCommand();
901                     }));
902                     ContextMenu.Commands.Add(new UICommand(map.GetValue("PasteMenuName", context).ValueAsString, async (command) =>
903                     {
904                         await this.PasteCommand();
905                     }));
906                     if (this._Controller.RectSelection)
907                     {
908                         ContextMenu.Commands.Add(new UICommand(map.GetValue("LineSelectMenuName", context).ValueAsString, (command) =>
909                         {
910                             this._Controller.RectSelection = false;
911                         }));
912                     }
913                     else
914                     {
915                         ContextMenu.Commands.Add(new UICommand(map.GetValue("RectSelectMenuName", context).ValueAsString, (command) =>
916                         {
917                             this._Controller.RectSelection = true;
918                         }));
919                     }
920                     await ContextMenu.ShowAsync(Util.GetScreentPoint(e.Position,this));
921                 }
922             }
923         }
924
925         void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e)
926         {
927             bool touched = e.PointerDeviceType == PointerDeviceType.Touch;
928             this.Document.SelectGrippers.BottomLeft.Enabled = false;
929             this.Document.SelectGrippers.BottomRight.Enabled = touched;
930             this.JumpCaret(e.Position);
931             System.Diagnostics.Debug.WriteLine(e.TapCount);
932             if (e.TapCount == 2)
933             {
934                 this.Document.SelectGrippers.BottomLeft.Enabled = touched;
935                 //タッチスクリーンでダブルタップした場合、アンカーインデックスを単語の先頭にしないとバグる
936                 this.Controller.SelectWord(this.Controller.SelectionStart, touched);
937             }
938         }
939
940         void JumpCaret(Point p)
941         {
942             TextPoint tp = this.View.GetTextPointFromPostion(p);
943             if (tp == TextPoint.Null)
944                 return;
945
946             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
947
948             FoldingItem foldingData = this.View.HitFoldingData(p.X, tp.row);
949             if (foldingData != null)
950             {
951                 if (foldingData.Expand)
952                     this.View.LayoutLines.FoldingCollection.Collapse(foldingData);
953                 else
954                     this.View.LayoutLines.FoldingCollection.Expand(foldingData);
955                 this._Controller.JumpCaret(foldingData.Start, false);
956             }
957             else
958             {
959                 this._Controller.JumpCaret(tp.row, tp.col, false);
960             }
961             if (this.peer != null)
962                 this.peer.OnNotifyCaretChanged();
963             this.View.IsFocused = true;
964             this.Focus(FocusState.Programmatic);
965             this.Refresh();
966         }
967
968         void gestureRecongnizer_Dragging(GestureRecognizer sender, DraggingEventArgs e)
969         {
970             Point p = e.Position;
971             if (this.View.HitTextArea(p.X, p.Y))
972             {
973                 TextPoint tp = this.View.GetTextPointFromPostion(p);
974                 this._Controller.MoveCaretAndSelect(tp);
975                 if (this.peer != null)
976                     this.peer.OnNotifyCaretChanged();
977                 this.Refresh();
978             }
979         }
980
981         bool IsModiferKeyPressed(VirtualKey key)
982         {
983             CoreVirtualKeyStates state = Window.Current.CoreWindow.GetKeyState(key);
984             return (state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
985         }
986         void Refresh(Rectangle updateRect)
987         {
988             if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed)
989                 return;
990
991             this.Render.BegineDraw();
992             if (this.IsEnabled)
993                 this.View.Draw(updateRect);
994             else
995                 this.Render.FillBackground(updateRect);
996             this.Render.EndDraw();
997         }
998
999
1000         bool Resize(double width, double height)
1001         {
1002             if (width == 0 || height == 0)
1003                 throw new ArgumentOutOfRangeException();
1004             if (this.Render.Resize(this.rectangle, width, height))
1005             {
1006                 this.View.PageBound = new Rectangle(0, 0, width, height);
1007
1008                 if (this.horizontalScrollBar != null)
1009                 {
1010                     this.horizontalScrollBar.LargeChange = this.View.PageBound.Width;
1011                     this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
1012                 }
1013                 if (this.verticalScrollBar != null)
1014                 {
1015                     this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen;
1016                     this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
1017                 }
1018                 return true;
1019             }
1020             return false;
1021         }
1022
1023         void View_SrcChanged(object sender, EventArgs e)
1024         {
1025             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
1026                 return;
1027             EditView view = this.View;
1028             if (view.Src.Row > this.verticalScrollBar.Maximum)
1029                 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
1030             double absoulteX = Math.Abs(view.Src.X);
1031             if (absoulteX > this.horizontalScrollBar.Maximum)
1032                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
1033             if (view.Src.Row != this.verticalScrollBar.Value)
1034                 this.verticalScrollBar.Value = view.Src.Row;
1035             if (view.Src.X != this.horizontalScrollBar.Value)
1036                 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
1037         }
1038
1039         void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
1040         {
1041             if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
1042             {
1043                 this.Refresh();
1044                 return;
1045             }
1046         }
1047
1048         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
1049         {
1050             if (this.horizontalScrollBar == null)
1051                 return;
1052             double toX;
1053             if (this.FlowDirection == FlowDirection.LeftToRight)
1054                 toX = this.horizontalScrollBar.Value;
1055             else
1056                 toX = -this.horizontalScrollBar.Value;
1057             this._Controller.Scroll(toX, this.View.Src.Row, false, false);
1058             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1059             this.Document.SelectGrippers.BottomRight.Enabled = false;
1060             this.Refresh();
1061         }
1062
1063         void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
1064         {
1065             if (this.verticalScrollBar == null)
1066                 return;
1067             int newRow = (int)this.verticalScrollBar.Value;
1068             if (newRow >= this.View.LayoutLines.Count)
1069                 return;
1070             this._Controller.Scroll(this.View.Src.X, newRow, false, false);
1071             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1072             this.Document.SelectGrippers.BottomRight.Enabled = false;
1073             this.Refresh();
1074         }
1075
1076         void Document_Update(object sender, DocumentUpdateEventArgs e)
1077         {
1078             if (this.textStore.IsLocked())
1079                 return;
1080             if (e.type == UpdateType.Replace)
1081                 TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);
1082         }
1083
1084         void FooTextBox_Loaded(object sender, RoutedEventArgs e)
1085         {
1086             this.Focus(FocusState.Programmatic);
1087         }
1088
1089         void timer_Tick(object sender, object e)
1090         {
1091             bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding();
1092             if (updateAll)
1093                 this.Refresh();
1094         }
1095
1096         /// <inheritdoc/>
1097         public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
1098         {
1099             FooTextBox source = (FooTextBox)sender;
1100             if (e.Property.Equals(IndentModeProperty))
1101                 source.Controller.IndentMode = source.IndentMode;
1102             if (e.Property.Equals(SelectionProperty) && !source.nowCaretMove)
1103                 source._Controller.Select(source.Selection.Index,source.Selection.Length);
1104             if (e.Property.Equals(CaretPostionPropertyKey) && !source.nowCaretMove)
1105                 source.JumpCaret(source.CaretPostion.row, source.CaretPostion.col);
1106             if (e.Property.Equals(InsertModeProperty))
1107                 source.View.InsertMode = source.InsertMode;
1108             if (e.Property.Equals(TabCharsProperty))
1109                 source.Document.TabStops = source.TabChars;
1110             if (e.Property.Equals(RectSelectModeProperty))
1111                 source._Controller.RectSelection = source.RectSelectMode;
1112             if (e.Property.Equals(DrawCaretProperty))
1113                 source.View.HideCaret = !source.DrawCaret;
1114             if (e.Property.Equals(DrawCaretLineProperty))
1115                 source.View.HideLineMarker = !source.DrawCaretLine;
1116             if (e.Property.Equals(DrawLineNumberProperty))
1117                 source.Document.DrawLineNumber = source.DrawLineNumber;
1118             if(e.Property.Equals(MagnificationPowerPropertyKey))
1119                 source.Render.FontSize = source.FontSize * source.MagnificationPower;
1120             if (e.Property.Equals(FontFamilyProperty))
1121                 source.Render.FontFamily = source.FontFamily;
1122             if (e.Property.Equals(FontStyleProperty))
1123                 source.Render.FontStyle = source.FontStyle;
1124             if (e.Property.Equals(FontWeightProperty))
1125                 source.Render.FontWeigth = source.FontWeight;
1126             if (e.Property.Equals(FontSizeProperty))
1127                 source.Render.FontSize = source.FontSize;
1128             if (e.Property.Equals(ForegroundProperty))
1129                 source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground);
1130             if (e.Property.Equals(BackgroundProperty))
1131                 source.Render.Background = D2DRenderBase.ToColor4(source.Background);
1132             if (e.Property.Equals(ControlCharProperty))
1133                 source.Render.ControlChar = D2DRenderBase.ToColor4(source.ControlChar);
1134             if (e.Property.Equals(HilightProperty))
1135                 source.Render.Hilight = D2DRenderBase.ToColor4(source.Hilight);
1136             if (e.Property.Equals(Keyword1Property))
1137                 source.Render.Keyword1 = D2DRenderBase.ToColor4(source.Keyword1);
1138             if (e.Property.Equals(Keyword2Property))
1139                 source.Render.Keyword2 = D2DRenderBase.ToColor4(source.Keyword2);
1140             if (e.Property.Equals(CommentProperty))
1141                 source.Render.Comment = D2DRenderBase.ToColor4(source.Comment);
1142             if (e.Property.Equals(LiteralProperty))
1143                 source.Render.Literal = D2DRenderBase.ToColor4(source.Literal);
1144             if (e.Property.Equals(URLProperty))
1145                 source.Render.Url = D2DRenderBase.ToColor4(source.URL);
1146             if (e.Property.Equals(InsertCaretProperty))
1147                 source.Render.InsertCaret = D2DRenderBase.ToColor4(source.InsertCaret);
1148             if (e.Property.Equals(OverwriteCaretProperty))
1149                 source.Render.OverwriteCaret = D2DRenderBase.ToColor4(source.OverwriteCaret);
1150             if (e.Property.Equals(PaddingProperty))
1151                 source.View.Padding = new Padding((int)source.Padding.Left, (int)source.Padding.Top, (int)source.Padding.Right, (int)source.Padding.Bottom);
1152             if (e.Property.Equals(LineMarkerProperty))
1153                 source.Render.LineMarker = D2DRenderBase.ToColor4(source.LineMarker);
1154             if (e.Property.Equals(MarkURLProperty))
1155                 source.Document.UrlMark = source.MarkURL;
1156             if (e.Property.Equals(ShowFullSpaceProperty))
1157                 source.Render.ShowFullSpace = source.ShowFullSpace;
1158             if (e.Property.Equals(ShowHalfSpaceProperty))
1159                 source.Render.ShowHalfSpace = source.ShowHalfSpace;
1160             if (e.Property.Equals(ShowTabProperty))
1161                 source.Render.ShowTab = source.ShowTab;
1162             if (e.Property.Equals(ShowLineBreakProperty))
1163                 source.Render.ShowLineBreak = source.ShowLineBreak;
1164             if (e.Property.Equals(LineBreakProperty))
1165                 source.Document.LineBreak = source.LineBreakMethod;
1166             if (e.Property.Equals(LineBreakCharCountProperty))
1167                 source.Document.LineBreakCharCount = source.LineBreakCharCount;
1168             if (e.Property.Equals(UpdateAreaProperty))
1169                 source.Render.UpdateArea = D2DRenderBase.ToColor4(source.UpdateArea);
1170             if (e.Property.Equals(LineNumberProperty))
1171                 source.Render.LineNumber = D2DRenderBase.ToColor4(source.LineNumber);
1172             if (e.Property.Equals(FlowDirectionProperty))
1173             {
1174                 source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft;
1175                 if(source.horizontalScrollBar != null)
1176                     source.horizontalScrollBar.FlowDirection = source.FlowDirection;
1177             }
1178             if (e.Property.Equals(DrawRulerProperty))
1179             {
1180                 source.Document.HideRuler = !source.DrawRuler;
1181                 source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col);
1182             }
1183         }
1184         #endregion
1185
1186         #region event
1187         
1188         /// <summary>
1189         /// コンテキストメニューが表示されるときに呼び出されます
1190         /// </summary>
1191         public event EventHandler<FooContextMenuEventArgs> ContextMenuOpening;
1192
1193         #endregion
1194
1195         #region property
1196
1197         internal Controller Controller
1198         {
1199             get
1200             {
1201                 return this._Controller;
1202             }
1203         }
1204
1205         /// <summary>
1206         /// 文字列の描写に使用されるアンチエイリアシング モードを表します
1207         /// </summary>
1208         public TextAntialiasMode TextAntialiasMode
1209         {
1210             get
1211             {
1212                 return this.Render.TextAntialiasMode;
1213             }
1214             set
1215             {
1216                 this.Render.TextAntialiasMode = value;
1217             }
1218         }
1219
1220         /// <summary>
1221         /// シンタックスハイライターを表す
1222         /// </summary>
1223         public IHilighter Hilighter
1224         {
1225             get
1226             {
1227                 return this.View.Hilighter;
1228             }
1229             set
1230             {
1231                 this.View.Hilighter = value;
1232                 this.View.LayoutLines.ClearLayoutCache();
1233             }
1234         }
1235
1236         /// <summary>
1237         /// フォールティングを作成するインターフェイスを表す
1238         /// </summary>
1239         public IFoldingStrategy FoldingStrategy
1240         {
1241             get
1242             {
1243                 return this.View.LayoutLines.FoldingStrategy;
1244             }
1245             set
1246             {
1247                 this.View.LayoutLines.FoldingStrategy = value;
1248                 if (value == null)
1249                     this.View.LayoutLines.FoldingCollection.Clear();
1250             }
1251         }
1252
1253         /// <summary>
1254         /// マーカーパターンセットを表す
1255         /// </summary>
1256         public MarkerPatternSet MarkerPatternSet
1257         {
1258             get
1259             {
1260                 return this.Document.MarkerPatternSet;
1261             }
1262         }
1263
1264         /// <summary>
1265         /// ドキュメントを表す
1266         /// </summary>
1267         public Document Document
1268         {
1269             get;
1270             private set;
1271         }
1272
1273         /// <summary>
1274         /// レイアウト行を表す
1275         /// </summary>
1276         public LineToIndexTable LayoutLineCollection
1277         {
1278             get { return this.View.LayoutLines; }
1279         }
1280
1281         /// <summary>
1282         /// 選択中の文字列を表す
1283         /// </summary>
1284         public string SelectedText
1285         {
1286             get
1287             {
1288                 return this._Controller.SelectedText;
1289             }
1290             set
1291             {
1292                 int oldLength = this.Document.Length;
1293                 this._Controller.SelectedText = value;
1294             }
1295         }
1296
1297         /// <summary>
1298         /// インデントの方法を表す
1299         /// </summary>
1300         public IndentMode IndentMode
1301         {
1302             get { return (IndentMode)GetValue(IndentModeProperty); }
1303             set { SetValue(IndentModeProperty, value); }
1304         }
1305
1306         /// <summary>
1307         /// IndentModeの依存プロパティを表す
1308         /// </summary>
1309         public static readonly DependencyProperty IndentModeProperty =
1310             DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab,OnPropertyChanged));
1311
1312         /// <summary>
1313         /// 選択範囲を表す
1314         /// </summary>
1315         /// <remarks>
1316         /// Lengthが0の場合はキャレット位置を表します。
1317         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
1318         /// </remarks>
1319         public TextRange Selection
1320         {
1321             get { return (TextRange)GetValue(SelectionProperty); }
1322             set { SetValue(SelectionProperty, value); }
1323         }
1324
1325         /// <summary>
1326         /// Selectionの依存プロパティを表す
1327         /// </summary>
1328         public static readonly DependencyProperty SelectionProperty =
1329             DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(0));
1330
1331         /// <summary>
1332         /// 拡大率を表す
1333         /// </summary>
1334         public double MagnificationPower
1335         {
1336             get { return (double)GetValue(MagnificationPowerPropertyKey); }
1337             set { SetValue(MagnificationPowerPropertyKey, value); }
1338         }
1339
1340         /// <summary>
1341         /// 拡大率を表す依存プロパティ
1342         /// </summary>
1343         public static readonly DependencyProperty MagnificationPowerPropertyKey =
1344             DependencyProperty.Register("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0, OnPropertyChanged));
1345
1346         /// <summary>
1347         /// キャレット位置を表す
1348         /// </summary>
1349         public TextPoint CaretPostion
1350         {
1351             get { return (TextPoint)GetValue(CaretPostionPropertyKey); }
1352             set { SetValue(CaretPostionPropertyKey, value); }
1353         }
1354
1355         static readonly DependencyProperty CaretPostionPropertyKey =
1356             DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(new TextPoint(), OnPropertyChanged));
1357
1358         /// <summary>
1359         /// レタリング方向を表す
1360         /// </summary>
1361         public new FlowDirection FlowDirection
1362         {
1363             get { return (FlowDirection)GetValue(FlowDirectionProperty); }
1364             set { SetValue(FlowDirectionProperty, value); }
1365         }
1366
1367         /// <summary>
1368         /// レタリング方向を表す。これは依存プロパティです
1369         /// </summary>
1370         public new static readonly DependencyProperty FlowDirectionProperty =
1371             DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight,OnPropertyChanged));
1372
1373         /// <summary>
1374         /// フォントファミリーを表す
1375         /// </summary>
1376         public new FontFamily FontFamily
1377         {
1378             get { return (FontFamily)GetValue(FontFamilyProperty); }
1379             set { SetValue(FontFamilyProperty, value); }
1380         }
1381
1382         /// <summary>
1383         /// FontFamilyの依存プロパティを表す
1384         /// </summary>
1385         public new static readonly DependencyProperty FontFamilyProperty =
1386             DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(FooTextBox), new PropertyMetadata(new FontFamily("Cambria"), OnPropertyChanged));
1387
1388         /// <summary>
1389         /// フォントサイズを表す
1390         /// </summary>
1391         public new double FontSize
1392         {
1393             get { return (double)GetValue(FontSizeProperty); }
1394             set { SetValue(FontSizeProperty, value); }
1395         }
1396
1397         /// <summary>
1398         /// FontSizeの依存プロパティを表す
1399         /// </summary>
1400         public new static readonly DependencyProperty FontSizeProperty =
1401             DependencyProperty.Register("FontSize", typeof(double), typeof(FooTextBox), new PropertyMetadata(12.0,OnPropertyChanged));
1402
1403         /// <summary>
1404         /// フォントスタイルを表す
1405         /// </summary>
1406         public new FontStyle FontStyle
1407         {
1408             get { return (FontStyle)GetValue(FontStyleProperty); }
1409             set { SetValue(FontStyleProperty, value); }
1410         }
1411
1412         /// <summary>
1413         /// FontStyleの依存プロパティを表す
1414         /// </summary>
1415         public new static readonly DependencyProperty FontStyleProperty =
1416             DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(FooTextBox), new PropertyMetadata(FontStyle.Normal,OnPropertyChanged));
1417
1418         /// <summary>
1419         /// フォントの幅を表す
1420         /// </summary>
1421         public new FontWeight FontWeight
1422         {
1423             get { return (FontWeight)GetValue(FontWeightProperty); }
1424             set { SetValue(FontWeightProperty, value); }
1425         }
1426
1427         /// <summary>
1428         /// FontWeigthの依存プロパティを表す
1429         /// </summary>
1430         public new static readonly DependencyProperty FontWeightProperty =
1431             DependencyProperty.Register("FontWeigth", typeof(FontWeight), typeof(FooTextBox), new PropertyMetadata(FontWeights.Normal,OnPropertyChanged));
1432
1433         /// <summary>
1434         /// デフォルトの文字色を表す。これは依存プロパティです
1435         /// </summary>
1436         public new Windows.UI.Color Foreground
1437         {
1438             get { return (Windows.UI.Color)GetValue(ForegroundProperty); }
1439             set { SetValue(ForegroundProperty, value); }
1440         }
1441
1442         /// <summary>
1443         /// Foregroundの依存プロパティを表す
1444         /// </summary>
1445         public new static readonly DependencyProperty ForegroundProperty =
1446             DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1447
1448         /// <summary>
1449         /// 背景色を表す。これは依存プロパティです
1450         /// </summary>
1451         public new Windows.UI.Color Background
1452         {
1453             get { return (Windows.UI.Color)GetValue(BackgroundProperty); }
1454             set { SetValue(BackgroundProperty, value); }
1455         }
1456
1457         /// <summary>
1458         /// Backgroundの依存プロパティを表す
1459         /// </summary>
1460         public new static readonly DependencyProperty BackgroundProperty =
1461             DependencyProperty.Register("Background", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
1462
1463         /// <summary>
1464         /// コントロールコードの文字色を表す。これは依存プロパティです
1465         /// </summary>
1466         public Windows.UI.Color ControlChar
1467         {
1468             get { return (Windows.UI.Color)GetValue(ControlCharProperty); }
1469             set { SetValue(ControlCharProperty, value); }
1470         }
1471
1472         /// <summary>
1473         /// ControlCharの依存プロパティを表す
1474         /// </summary>
1475         public static readonly DependencyProperty ControlCharProperty =
1476             DependencyProperty.Register("ControlChar", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1477
1478         /// <summary>
1479         /// 選択時の背景色を表す。これは依存プロパティです
1480         /// </summary>
1481         public Windows.UI.Color Hilight
1482         {
1483             get { return (Windows.UI.Color)GetValue(HilightProperty); }
1484             set { SetValue(HilightProperty, value); }
1485         }
1486
1487         /// <summary>
1488         /// Hilightの依存プロパティを表す
1489         /// </summary>
1490         public static readonly DependencyProperty HilightProperty =
1491             DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DeepSkyBlue, OnPropertyChanged));
1492
1493         /// <summary>
1494         /// キーワード1の文字色を表す。これは依存プロパティです
1495         /// </summary>
1496         public Windows.UI.Color Keyword1
1497         {
1498             get { return (Windows.UI.Color)GetValue(Keyword1Property); }
1499             set { SetValue(Keyword1Property, value); }
1500         }
1501
1502         /// <summary>
1503         /// Keyword1の依存プロパティを表す
1504         /// </summary>
1505         public static readonly DependencyProperty Keyword1Property =
1506             DependencyProperty.Register("Keyword1", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1507
1508         /// <summary>
1509         /// キーワード2の文字色を表す。これは依存プロパティです
1510         /// </summary>
1511         public Windows.UI.Color Keyword2
1512         {
1513             get { return (Windows.UI.Color)GetValue(Keyword2Property); }
1514             set { SetValue(Keyword2Property, value); }
1515         }
1516
1517         /// <summary>
1518         /// Keyword2の依存プロパティを表す
1519         /// </summary>
1520         public static readonly DependencyProperty Keyword2Property =
1521             DependencyProperty.Register("Keyword2", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DarkCyan, OnPropertyChanged));
1522
1523         /// <summary>
1524         /// コメントの文字色を表す。これは依存プロパティです
1525         /// </summary>
1526         public Windows.UI.Color Comment
1527         {
1528             get { return (Windows.UI.Color)GetValue(CommentProperty); }
1529             set { SetValue(CommentProperty, value); }
1530         }
1531
1532         /// <summary>
1533         /// Commentの依存プロパティを表す
1534         /// </summary>
1535         public static readonly DependencyProperty CommentProperty =
1536             DependencyProperty.Register("Comment", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Green, OnPropertyChanged));
1537
1538         /// <summary>
1539         /// 文字リテラルの文字色を表す。これは依存プロパティです
1540         /// </summary>
1541         public Windows.UI.Color Literal
1542         {
1543             get { return (Windows.UI.Color)GetValue(LiteralProperty); }
1544             set { SetValue(LiteralProperty, value); }
1545         }
1546
1547         /// <summary>
1548         /// Literalの依存プロパティを表す
1549         /// </summary>
1550         public static readonly DependencyProperty LiteralProperty =
1551             DependencyProperty.Register("Literal", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Brown, OnPropertyChanged));
1552
1553         /// <summary>
1554         /// URLの文字色を表す。これは依存プロパティです
1555         /// </summary>
1556         public Windows.UI.Color URL
1557         {
1558             get { return (Windows.UI.Color)GetValue(URLProperty); }
1559             set { SetValue(URLProperty, value); }
1560         }
1561
1562         /// <summary>
1563         /// URLの依存プロパティを表す
1564         /// </summary>
1565         public static readonly DependencyProperty URLProperty =
1566             DependencyProperty.Register("URL", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged));
1567
1568         /// <summary>
1569         /// 行更新フラグの色を表す
1570         /// </summary>
1571         public Windows.UI.Color UpdateArea
1572         {
1573             get { return (Windows.UI.Color)GetValue(UpdateAreaProperty); }
1574             set { SetValue(UpdateAreaProperty, value); }
1575         }
1576
1577         /// <summary>
1578         /// UpdateAreaの依存プロパティを表す
1579         /// </summary>
1580         public static readonly DependencyProperty UpdateAreaProperty =
1581             DependencyProperty.Register("UpdateArea", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));
1582
1583         /// <summary>
1584         /// ラインマーカーの色を表す
1585         /// </summary>
1586         public Windows.UI.Color LineMarker
1587         {
1588             get { return (Windows.UI.Color)GetValue(LineMarkerProperty); }
1589             set { SetValue(LineMarkerProperty, value); }
1590         }
1591
1592         /// <summary>
1593         /// LineMarkerの依存プロパティを表す
1594         /// </summary>
1595         public static readonly DependencyProperty LineMarkerProperty =
1596             DependencyProperty.Register("LineMarker", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged));
1597
1598         /// <summary>
1599         /// 挿入モード時のキャレットの色を表す
1600         /// </summary>
1601         public Windows.UI.Color InsertCaret
1602         {
1603             get { return (Windows.UI.Color)GetValue(InsertCaretProperty); }
1604             set { SetValue(InsertCaretProperty, value); }
1605         }
1606
1607         /// <summary>
1608         /// InsertCaretの依存プロパティを表す
1609         /// </summary>
1610         public static readonly DependencyProperty InsertCaretProperty =
1611             DependencyProperty.Register("InsertCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1612
1613         /// <summary>
1614         /// 上書きモード時のキャレット職を表す
1615         /// </summary>
1616         public Windows.UI.Color OverwriteCaret
1617         {
1618             get { return (Windows.UI.Color)GetValue(OverwriteCaretProperty); }
1619             set { SetValue(OverwriteCaretProperty, value); }
1620         }
1621
1622         /// <summary>
1623         /// OverwriteCaretの依存プロパティを表す
1624         /// </summary>
1625         public static readonly DependencyProperty OverwriteCaretProperty =
1626             DependencyProperty.Register("OverwriteCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
1627
1628         /// <summary>
1629         /// 行番号の色を表す
1630         /// </summary>
1631         public Windows.UI.Color LineNumber
1632         {
1633             get { return (Windows.UI.Color)GetValue(LineNumberProperty); }
1634             set { SetValue(LineNumberProperty, value); }
1635         }
1636
1637         /// <summary>
1638         /// Using a DependencyProperty as the backing store for LineNumber.  This enables animation, styling, binding, etc...
1639         /// </summary>
1640         public static readonly DependencyProperty LineNumberProperty =
1641             DependencyProperty.Register("LineNumber", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray,OnPropertyChanged));
1642
1643         /// <summary>
1644         /// 余白を表す
1645         /// </summary>
1646         public new Thickness Padding
1647         {
1648             get { return (Thickness)GetValue(PaddingProperty); }
1649             set { SetValue(PaddingProperty, value); }
1650         }
1651
1652         /// <summary>
1653         /// Paddingの依存プロパティを表す
1654         /// </summary>
1655         public new static readonly DependencyProperty PaddingProperty =
1656             DependencyProperty.Register("Padding", typeof(Thickness), typeof(FooTextBox), new PropertyMetadata(new Thickness(),OnPropertyChanged));        
1657
1658         /// <summary>
1659         /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
1660         /// </summary>
1661         public bool InsertMode
1662         {
1663             get { return (bool)GetValue(InsertModeProperty); }
1664             set { SetValue(InsertModeProperty, value); }
1665         }
1666
1667         /// <summary>
1668         /// InsertModeの依存プロパティを表す
1669         /// </summary>
1670         public static readonly DependencyProperty InsertModeProperty =
1671             DependencyProperty.Register("InsertMode",
1672             typeof(bool),
1673             typeof(FooTextBox),
1674             new PropertyMetadata(true, OnPropertyChanged));
1675
1676         /// <summary>
1677         /// タブの文字数を表す。これは依存プロパティです
1678         /// </summary>
1679         public int TabChars
1680         {
1681             get { return (int)GetValue(TabCharsProperty); }
1682             set { SetValue(TabCharsProperty, value); }
1683         }
1684
1685         /// <summary>
1686         /// TabCharsの依存プロパティを表す
1687         /// </summary>
1688         public static readonly DependencyProperty TabCharsProperty =
1689             DependencyProperty.Register("TabChars",
1690             typeof(int),
1691             typeof(FooTextBox),
1692             new PropertyMetadata(4, OnPropertyChanged));
1693
1694         /// <summary>
1695         /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
1696         /// </summary>
1697         public bool RectSelectMode
1698         {
1699             get { return (bool)GetValue(RectSelectModeProperty); }
1700             set { SetValue(RectSelectModeProperty, value); }
1701         }
1702
1703         /// <summary>
1704         /// RectSelectModeの依存プロパティを表す
1705         /// </summary>
1706         public static readonly DependencyProperty RectSelectModeProperty =
1707             DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1708
1709         /// <summary>
1710         /// 折り返しの方法を指定する
1711         /// </summary>
1712         /// <remarks>
1713         /// 変更した場合、レイアウトの再構築を行う必要があります
1714         /// </remarks>
1715         public LineBreakMethod LineBreakMethod
1716         {
1717             get { return (LineBreakMethod)GetValue(LineBreakProperty); }
1718             set { SetValue(LineBreakProperty, value); }
1719         }
1720
1721         /// <summary>
1722         /// LineBreakMethodの依存プロパティを表す
1723         /// </summary>
1724         public static readonly DependencyProperty LineBreakProperty =
1725             DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None, OnPropertyChanged));
1726
1727
1728         /// <summary>
1729         /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
1730         /// </summary>
1731         /// <remarks>
1732         /// 変更した場合、レイアウトの再構築を行う必要があります
1733         /// </remarks>
1734         public int LineBreakCharCount
1735         {
1736             get { return (int)GetValue(LineBreakCharCountProperty); }
1737             set { SetValue(LineBreakCharCountProperty, value); }
1738         }
1739
1740         /// <summary>
1741         /// LineBreakCharCountの依存プロパティを表す
1742         /// </summary>
1743         public static readonly DependencyProperty LineBreakCharCountProperty =
1744             DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));        
1745
1746         /// <summary>
1747         /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1748         /// </summary>
1749         public bool DrawCaret
1750         {
1751             get { return (bool)GetValue(DrawCaretProperty); }
1752             set { SetValue(DrawCaretProperty, value); }
1753         }
1754
1755         /// <summary>
1756         /// DrawCaretの依存プロパティを表す
1757         /// </summary>
1758         public static readonly DependencyProperty DrawCaretProperty =
1759             DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new PropertyMetadata(true, OnPropertyChanged));
1760
1761
1762         /// <summary>
1763         /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1764         /// </summary>
1765         public bool DrawCaretLine
1766         {
1767             get { return (bool)GetValue(DrawCaretLineProperty); }
1768             set { SetValue(DrawCaretLineProperty, value); }
1769         }
1770
1771         /// <summary>
1772         /// DrawCaretLineの依存プロパティを表す
1773         /// </summary>
1774         public static readonly DependencyProperty DrawCaretLineProperty =
1775             DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1776
1777         /// <summary>
1778         /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
1779         /// </summary>
1780         public bool DrawLineNumber
1781         {
1782             get { return (bool)GetValue(DrawLineNumberProperty); }
1783             set { SetValue(DrawLineNumberProperty, value); }
1784         }
1785
1786         /// <summary>
1787         /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
1788         /// </summary>
1789         public bool DrawRuler
1790         {
1791             get { return (bool)GetValue(DrawRulerProperty); }
1792             set { SetValue(DrawRulerProperty, value); }
1793         }
1794
1795         /// <summary>
1796         /// DrawRulerの依存プロパティを表す
1797         /// </summary>
1798         public static readonly DependencyProperty DrawRulerProperty =
1799             DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1800
1801
1802         /// <summary>
1803         /// DrawLineNumberの依存プロパティを表す
1804         /// </summary>
1805         public static readonly DependencyProperty DrawLineNumberProperty =
1806             DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1807
1808         /// <summary>
1809         /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
1810         /// </summary>
1811         public bool MarkURL
1812         {
1813             get { return (bool)GetValue(MarkURLProperty); }
1814             set { SetValue(MarkURLProperty, value); }
1815         }
1816
1817         /// <summary>
1818         /// MarkURLの依存プロパティを表す
1819         /// </summary>
1820         public static readonly DependencyProperty MarkURLProperty =
1821             DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1822
1823         /// <summary>
1824         /// 全角スペースを表示するなら真。そうでないなら偽
1825         /// </summary>
1826         public bool ShowFullSpace
1827         {
1828             get { return (bool)GetValue(ShowFullSpaceProperty); }
1829             set { SetValue(ShowFullSpaceProperty, value); }
1830         }
1831
1832         /// <summary>
1833         /// ShowFullSpaceの依存プロパティを表す
1834         /// </summary>
1835         public static readonly DependencyProperty ShowFullSpaceProperty =
1836             DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1837
1838         /// <summary>
1839         /// 半角スペースを表示するなら真。そうでないなら偽
1840         /// </summary>
1841         public bool ShowHalfSpace
1842         {
1843             get { return (bool)GetValue(ShowHalfSpaceProperty); }
1844             set { SetValue(ShowHalfSpaceProperty, value); }
1845         }
1846
1847         /// <summary>
1848         /// ShowHalfSpaceの依存プロパティを表す
1849         /// </summary>
1850         public static readonly DependencyProperty ShowHalfSpaceProperty =
1851             DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1852
1853         /// <summary>
1854         /// タブを表示するなら真。そうでないなら偽
1855         /// </summary>
1856         public bool ShowTab
1857         {
1858             get { return (bool)GetValue(ShowTabProperty); }
1859             set { SetValue(ShowTabProperty, value); }
1860         }
1861
1862         /// <summary>
1863         /// ShowTabの依存プロパティを表す
1864         /// </summary>
1865         public static readonly DependencyProperty ShowTabProperty =
1866             DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged));
1867
1868         /// <summary>
1869         /// 改行マークを表示するなら真。そうでないなら偽
1870         /// </summary>
1871         public bool ShowLineBreak
1872         {
1873             get { return (bool)GetValue(ShowLineBreakProperty); }
1874             set { SetValue(ShowLineBreakProperty, value); }
1875         }
1876
1877         /// <summary>
1878         /// ShowLineBreakの依存プロパティを表す
1879         /// </summary>
1880         public static readonly DependencyProperty ShowLineBreakProperty =
1881             DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false,OnPropertyChanged));
1882
1883         
1884         #endregion
1885
1886     }
1887     /// <summary>
1888     /// コンテキストメニューのイベントデーターを表す
1889     /// </summary>
1890     public class FooContextMenuEventArgs
1891     {
1892         /// <summary>
1893         /// 処理済みなら真。そうでないなら偽
1894         /// </summary>
1895         public bool Handled = false;
1896         /// <summary>
1897         /// コンテキストメニューを表示すべき座標を表す
1898         /// </summary>
1899         public Windows.Foundation.Point Postion;
1900         /// <summary>
1901         /// コンストラクター
1902         /// </summary>
1903         /// <param name="pos"></param>
1904         public FooContextMenuEventArgs(Windows.Foundation.Point pos)
1905         {
1906             this.Postion = pos;
1907         }
1908     }
1909 }