OSDN Git Service

バージョンナンバーを増やした
[fooeditengine/FooEditEngine.git] / WPF / 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.Threading.Tasks;
14 using System.Runtime.InteropServices;
15 using System.Windows;
16 using System.Windows.Input;
17 using System.Windows.Media;
18 using System.Windows.Controls;
19 using System.Windows.Controls.Primitives;
20 using System.Windows.Documents;
21 using System.Windows.Interop;
22 using System.Windows.Threading;
23 using DotNetTextStore;
24 using DotNetTextStore.UnmanagedAPI.TSF;
25 using DotNetTextStore.UnmanagedAPI.WinDef;
26 using Microsoft.Win32;
27
28 namespace FooEditEngine.WPF
29 {
30     /// <summary>
31     /// WPFでのFooTextBoxの実装
32     /// </summary>
33     public sealed class FooTextBox : Control, IDisposable
34     {
35         const double MaxFontSize = 72.0f;
36         const double MinFontSize = 1;
37
38         EditView _View;
39         Controller _Controller;
40         D2DRender Render;
41         Image image;
42         ScrollBar verticalScrollBar, horizontalScrollBar;
43         TextStore textStore;
44         DispatcherTimer timer;
45         bool disposed = false;
46         FooTextBoxAutomationPeer peer;
47         bool isNotifyChanged = false;
48         Document _Document;
49         Popup popup;
50
51         const int Interval = 96;
52         const int IntervalWhenLostFocuse = 160;
53
54         static FooTextBox()
55         {
56             DefaultStyleKeyProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(typeof(FooTextBox)));
57             KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(true));
58             KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(KeyboardNavigationMode.None));
59         }
60
61         /// <summary>
62         /// コンストラクター
63         /// </summary>
64         public FooTextBox()
65         {
66             this.popup = new Popup();
67
68             this.image = new Image();
69             this.image.Stretch = Stretch.Fill;
70             this.image.HorizontalAlignment = HorizontalAlignment.Left;
71             this.image.VerticalAlignment = VerticalAlignment.Top;
72
73             this.textStore = new TextStore();
74             this.textStore.IsLoading += textStore_IsLoading;
75             this.textStore.IsReadOnly += textStore_IsReadOnly;
76             this.textStore.GetStringLength += () => this.Document.Length;
77             this.textStore.GetString += _textStore_GetString;
78             this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex;
79             this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex;
80             this.textStore.InsertAtSelection += _textStore_InsertAtSelection;
81             this.textStore.GetHWnd += _textStore_GetHWnd;
82             this.textStore.GetScreenExtent += _textStore_GetScreenExtent;
83             this.textStore.GetStringExtent += _textStore_GetStringExtent;
84             this.textStore.CompositionStarted += textStore_CompositionStarted;
85             this.textStore.CompositionUpdated += textStore_CompositionUpdated;
86             this.textStore.CompositionEnded += textStore_CompositionEnded;
87
88             this.Render = new D2DRender(this, 200, 200,this.image);
89
90             this.Document = new Document();
91
92             this._View = new EditView(this.Document, this.Render, new Padding(5, 5, 5, 5));
93             this._View.SrcChanged += View_SrcChanged;
94             this._View.InsertMode = this.InsertMode;
95             this.Document.DrawLineNumber = this.DrawLineNumber;
96             this._View.HideCaret = !this.DrawCaret;
97             this._View.HideLineMarker = !this.DrawCaretLine;
98             this.Document.HideRuler = !this.DrawRuler;
99             this.Document.UrlMark = this.MarkURL;
100             this.Document.TabStops = this.TabChars;
101             this.Document.ShowFullSpace = this.ShowFullSpace;
102             this.Document.ShowHalfSpace = this.ShowHalfSpace;
103             this.Document.ShowTab = this.ShowTab;
104
105             this._Controller = new Controller(this.Document, this._View);
106             this._Document.SelectionChanged += new EventHandler(Controller_SelectionChanged);
107
108             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, CopyCommand, CanExecute));
109             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, CutCommand, CanExecute));
110             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, PasteCommand, CanExecute));
111             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, DeleteCommand, CanExecute));
112             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, SelectAllCommand, CanExecute));
113             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, UndoCommand, CanExecute));
114             this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, RedoCommand, CanExecute));
115             this.CommandBindings.Add(new CommandBinding(EditingCommands.ToggleInsert, ToggleInsertCommand, CanExecute));
116             this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleRectSelectMode, ToggleRectSelectCommand, CanExecute));
117             this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleFlowDirection, ToggleFlowDirectionCommand, CanExecute));
118             this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleCodePoint, ToggleCodePointCommand, CanExecute));
119
120             this.InputBindings.Add(new InputBinding(ApplicationCommands.Copy, new KeyGesture(Key.C, ModifierKeys.Control)));
121             this.InputBindings.Add(new InputBinding(ApplicationCommands.Cut, new KeyGesture(Key.X, ModifierKeys.Control)));
122             this.InputBindings.Add(new InputBinding(ApplicationCommands.Paste, new KeyGesture(Key.V, ModifierKeys.Control)));
123             this.InputBindings.Add(new InputBinding(ApplicationCommands.Delete, new KeyGesture(Key.Delete, ModifierKeys.None)));
124             this.InputBindings.Add(new InputBinding(ApplicationCommands.SelectAll, new KeyGesture(Key.A, ModifierKeys.Control)));
125             this.InputBindings.Add(new InputBinding(ApplicationCommands.Undo, new KeyGesture(Key.Z, ModifierKeys.Control)));
126             this.InputBindings.Add(new InputBinding(ApplicationCommands.Redo, new KeyGesture(Key.Y, ModifierKeys.Control)));
127             this.InputBindings.Add(new InputBinding(EditingCommands.ToggleInsert, new KeyGesture(Key.Insert, ModifierKeys.None)));
128             this.InputBindings.Add(new InputBinding(FooTextBoxCommands.ToggleCodePoint, new KeyGesture(Key.X, ModifierKeys.Alt)));
129
130             this.timer = new DispatcherTimer();
131             this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
132             this.timer.Tick += new EventHandler(timer_Tick);
133
134             this.Loaded += new RoutedEventHandler(FooTextBox_Loaded);
135
136             SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
137
138             this.SystemEvents_UserPreferenceChanged(null, new UserPreferenceChangedEventArgs(UserPreferenceCategory.Keyboard));
139
140             this.CaretMoved += (s, e) => { };
141
142             this.IsManipulationEnabled = true;
143         }
144
145         /// <summary>
146         /// ファイナライザー
147         /// </summary>
148         ~FooTextBox()
149         {
150             //Dispose(false)を呼び出すと落ちる
151             this.Dispose(false);
152         }
153
154         /// <summary>
155         /// テンプレートを適用します
156         /// </summary>
157         public override void OnApplyTemplate()
158         {
159             base.OnApplyTemplate();
160
161             Grid grid = this.GetTemplateChild("PART_Grid") as Grid;
162             if (grid != null)
163             {
164                 Grid.SetRow(this.image, 0);
165                 Grid.SetColumn(this.image, 0);
166                 grid.Children.Add(this.image);
167
168                 Grid.SetRow(this.popup, 0);
169                 Grid.SetColumn(this.popup, 0);
170                 grid.Children.Add(this.popup);
171                 //this.popup.PlacementTarget = this;
172                 this.popup.Placement = PlacementMode.Absolute;
173             }
174
175             this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
176             if (this.horizontalScrollBar != null)
177             {
178                 this.horizontalScrollBar.SmallChange = 10;
179                 this.horizontalScrollBar.LargeChange = 100;
180                 this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1;
181                 this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll);
182             }
183             this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;
184             if (this.verticalScrollBar != null)
185             {
186                 this.verticalScrollBar.SmallChange = 1;
187                 this.verticalScrollBar.LargeChange = 10;
188                 this.verticalScrollBar.Maximum = this.Document.LayoutLines.Count - 1;
189                 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
190             }
191         }
192
193         /// <summary>
194         /// ドキュメントを選択する
195         /// </summary>
196         /// <param name="start">開始インデックス</param>
197         /// <param name="length">長さ</param>
198         public void Select(int start, int length)
199         {
200             this.Document.Select(start, length);
201             this.textStore.NotifySelectionChanged();
202         }
203
204         /// <summary>
205         /// キャレットを指定した行に移動させます
206         /// </summary>
207         /// <param name="index">インデックス</param>
208         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
209         public void JumpCaret(int index)
210         {
211             this._Controller.JumpCaret(index);
212         }
213         /// <summary>
214         /// キャレットを指定した行と桁に移動させます
215         /// </summary>
216         /// <param name="row">行番号</param>
217         /// <param name="col">桁</param>
218         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
219         public void JumpCaret(int row, int col)
220         {
221             this._Controller.JumpCaret(row, col);
222         }
223
224         /// <summary>
225         /// 選択中のテキストをクリップボードにコピーします
226         /// </summary>
227         public void Copy()
228         {
229             string text = this._Controller.SelectedText;
230             if (text != null && text != string.Empty)
231                 Clipboard.SetText(text);
232         }
233
234         /// <summary>
235         /// 選択中のテキストをクリップボードに切り取ります
236         /// </summary>
237         public void Cut()
238         {
239             string text = this._Controller.SelectedText;
240             if (text != null && text != string.Empty)
241             {
242                 Clipboard.SetText(text);
243                 this._Controller.SelectedText = "";
244             }
245         }
246
247         /// <summary>
248         /// 選択中のテキストを貼り付けます
249         /// </summary>
250         public void Paste()
251         {
252             if (Clipboard.ContainsText() == false)
253                 return;
254             string text = Clipboard.GetText();
255             this._Controller.SelectedText = text;
256         }
257
258         /// <summary>
259         /// 選択を解除する
260         /// </summary>
261         public void DeSelectAll()
262         {
263             this._Controller.DeSelectAll();
264             this.textStore.NotifySelectionChanged();
265         }
266
267         /// <summary>
268         /// 対応する座標を返します
269         /// </summary>
270         /// <param name="tp">テキストポイント</param>
271         /// <returns>座標</returns>
272         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
273         public System.Windows.Point GetPostionFromTextPoint(TextPoint tp)
274         {
275             if (this.Document.FireUpdateEvent == false)
276                 throw new InvalidOperationException("");
277             return this.image.TranslatePoint(this._View.GetPostionFromTextPoint(tp),this);
278         }
279
280         /// <summary>
281         /// 対応するテキストポイントを返します
282         /// </summary>
283         /// <param name="p">クライアント領域の原点を左上とする座標</param>
284         /// <returns>テキストポイント</returns>
285         public TextPoint GetTextPointFromPostion(System.Windows.Point p)
286         {
287             if (this.Document.FireUpdateEvent == false)
288                 throw new InvalidOperationException("");
289             System.Windows.Point relP = this.TranslatePoint(p, this.image);
290             return this._View.GetTextPointFromPostion(p);
291         }
292
293         /// <summary>
294         /// 行の高さを取得します
295         /// </summary>
296         /// <param name="row">レイアウト行</param>
297         /// <returns>行の高さ</returns>
298         public double GetLineHeight(int row)
299         {
300             if (this.Document.FireUpdateEvent == false)
301                 throw new InvalidOperationException("");
302             return this._View.LayoutLines.GetLayout(row).Height;;
303         }
304
305         /// <summary>
306         /// インデックスに対応する座標を得ます
307         /// </summary>
308         /// <param name="index">インデックス</param>
309         /// <returns>座標を返す</returns>
310         public System.Windows.Point GetPostionFromIndex(int index)
311         {
312             if (this.Document.FireUpdateEvent == false)
313                 throw new InvalidOperationException("");
314             TextPoint tp = this._View.GetLayoutLineFromIndex(index);
315             return this._View.GetPostionFromTextPoint(tp);
316         }
317
318         /// <summary>
319         /// 座標からインデックスに変換します
320         /// </summary>
321         /// <param name="p">座標</param>
322         /// <returns>インデックスを返す</returns>
323         public int GetIndexFromPostion(System.Windows.Point p)
324         {
325             if (this.Document.FireUpdateEvent == false)
326                 throw new InvalidOperationException("");
327             TextPoint tp = this._View.GetTextPointFromPostion(p);
328             return this._View.GetIndexFromLayoutLine(tp);
329         }
330
331         /// <summary>
332         /// 再描写する
333         /// </summary>
334         public void Refresh()
335         {
336             this.Refresh(this._View.PageBound);
337         }
338
339         /// <summary>
340         /// レイアウト行をすべて破棄し、再度レイアウトを行う
341         /// </summary>
342         public void PerfomLayouts()
343         {
344             this.Document.PerformLayout();
345         }
346
347         /// <summary>
348         /// 指定行までスクロールする
349         /// </summary>
350         /// <param name="row">行</param>
351         /// <param name="alignTop">指定行を画面上に置くなら真。そうでないなら偽</param>
352         public void ScrollIntoView(int row, bool alignTop)
353         {
354             this._View.ScrollIntoView(row, alignTop);
355         }
356
357         /// <summary>
358         /// ストリームからドキュメントを構築する
359         /// </summary>
360         /// <param name="tr">TextReader</param>
361         /// <param name="token">キャンセル用トークン</param>
362         /// <returns>Taskオブジェクト</returns>
363         public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)
364         {
365             await this.Document.LoadAsync(tr, token);
366         }
367
368         /// <summary>
369         /// ファイルからドキュメントを構築する
370         /// </summary>
371         /// <param name="filepath">ファイルパス</param>
372         /// <param name="enc">エンコード</param>
373         /// <param name="token">キャンセル用トークン</param>
374         /// <returns>Taskオブジェクト</returns>
375         public async Task LoadFileAsync(string filepath, Encoding enc,System.Threading.CancellationTokenSource token)
376         {
377             var fs = new System.IO.StreamReader(filepath, enc);
378             await this.Document.LoadAsync(fs, token);
379             fs.Close();
380         }
381
382         private void Document_LoadProgress(object sender, ProgressEventArgs e)
383         {
384             if (e.state == ProgressState.Start)
385             {
386                 this.IsEnabled = false;
387             }
388             else if (e.state == ProgressState.Complete)
389             {
390                 TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);
391                 if (this.verticalScrollBar != null)
392                     this.verticalScrollBar.Maximum = this._View.LayoutLines.Count;
393                 this._View.CalculateWhloeViewPort();
394                 this._View.CalculateLineCountOnScreen();
395                 this.IsEnabled = true;
396                 this.Refresh(this._View.PageBound);
397             }
398         }
399
400         /// <summary>
401         /// ドキュメントの内容をファイルに保存する
402         /// </summary>
403         /// <param name="filepath">ファイルパス</param>
404         /// <param name="newLine">改行コード</param>
405         /// <param name="enc">エンコード</param>
406         /// <param name="token">キャンセル用トークン</param>
407         /// <returns>Taskオブジェクト</returns>
408         public async Task SaveFile(string filepath, Encoding enc,string newLine, System.Threading.CancellationTokenSource token)
409         {
410             var fs = new System.IO.StreamWriter(filepath, false , enc);
411             fs.NewLine = newLine;
412             await this.Document.SaveAsync(fs, token);
413             fs.Close();
414         }
415
416         /// <summary>
417         /// アンマネージドリソースを開放する
418         /// </summary>
419         public void Dispose()
420         {
421             if (this.disposed)
422                 return;
423             this.Dispose(true);
424             GC.SuppressFinalize(this);
425             this.disposed = true;
426         }
427
428         /// <summary>
429         /// リソースを開放する
430         /// </summary>
431         /// <param name="disposing">真ならマネージドリソースも開放し、そうでないならアンマネージドリソースのみを開放する</param>
432         void Dispose(bool disposing)
433         {
434             if (disposing)
435             {
436                 this.textStore.Dispose();
437                 this.timer.Stop();
438                 this._View.Dispose();
439                 this.Render.Dispose();
440             }
441             SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
442         }
443         
444         void Refresh(Rectangle updateRect)
445         {
446             if (this.disposed || this.Visibility == Visibility.Collapsed)
447                 return;
448
449             this.Render.DrawContent(this._View, this.IsEnabled, updateRect);
450             this.Document.IsRequestRedraw = false;
451         }
452
453         #region Commands
454         void CanExecute(object sender, CanExecuteRoutedEventArgs e)
455         {
456             e.CanExecute = this.IsEnabled;
457         }
458
459         void ToggleCodePointCommand(object sender, RoutedEventArgs e)
460         {
461             if (!this._Controller.ConvertToChar())
462                 this._Controller.ConvertToCodePoint();
463             this.Refresh();
464         }
465
466         void CopyCommand(object sender, RoutedEventArgs e)
467         {
468             this.Copy();
469         }
470
471         void CutCommand(object sender, RoutedEventArgs e)
472         {
473             this.Cut();
474             this.Refresh();
475         }
476
477         void PasteCommand(object sender, RoutedEventArgs e)
478         {
479             this.Paste();
480             this.Refresh();
481         }
482
483         void DeleteCommand(object sender, RoutedEventArgs e)
484         {
485             int oldLength = this.Document.Length;
486             this._Controller.DoDeleteAction();
487             this.Refresh();
488         }
489
490         void SelectAllCommand(object sender, RoutedEventArgs e)
491         {
492             this.Select(0, this.Document.Length);
493             this.Refresh();
494         }
495
496         void UndoCommand(object sender, RoutedEventArgs e)
497         {
498             int oldLength = this.Document.Length;
499             this.Document.UndoManager.undo();
500             this.Refresh();
501         }
502
503         void RedoCommand(object sender, RoutedEventArgs e)
504         {
505             int oldLength = this.Document.Length;
506             this.Document.UndoManager.redo();
507             this.Refresh();
508         }
509
510         void ToggleInsertCommand(object sender, RoutedEventArgs e)
511         {
512             if (this.InsertMode)
513                 this.InsertMode = false;
514             else
515                 this.InsertMode = true;
516             this.Refresh();
517         }
518
519         void ToggleRectSelectCommand(object sender, RoutedEventArgs e)
520         {
521             if (this.RectSelectMode)
522                 this.RectSelectMode = false;
523             else
524                 this.RectSelectMode = true;
525             this.Refresh();
526         }
527         void ToggleFlowDirectionCommand(object sender, RoutedEventArgs e)
528         {
529             if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
530                 this.FlowDirection = System.Windows.FlowDirection.RightToLeft;
531             else
532                 this.FlowDirection = System.Windows.FlowDirection.LeftToRight;
533             this.Refresh();
534         }
535         #endregion
536         #region TSF
537         internal TextStore TextStore
538         {
539             get { return this.textStore; }
540         }
541
542         bool textStore_IsReadOnly()
543         {
544             return false;
545         }
546
547         bool textStore_IsLoading()
548         {
549             return false;
550         }
551
552         void textStore_CompositionEnded()
553         {
554             TextStoreHelper.EndCompostion(this.Document);
555             this.Refresh();
556         }
557
558         void textStore_CompositionUpdated(int start, int end)
559         {
560             if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this._View, start, end))
561                 this.Refresh();
562         }
563         bool textStore_CompositionStarted()
564         {
565             bool result = TextStoreHelper.StartCompstion(this.Document);
566             if (!result)
567                 System.Media.SystemSounds.Beep.Play();
568             return result;
569         }
570
571         string _textStore_GetString(int start, int length)
572         {
573             return this.Document.ToString(start, length);
574         }
575
576         IntPtr _textStore_GetHWnd()
577         {
578             var hwndSource = HwndSource.FromVisual(this) as HwndSource;
579             if (hwndSource != null)
580                 return hwndSource.Handle;
581             else
582                 return IntPtr.Zero;
583         }
584
585         void _textStore_GetStringExtent(
586             int i_startIndex,
587             int i_endIndex,
588             out POINT o_topLeft,
589             out POINT o_bottomRight
590         )
591         {
592             Point startPos, endPos;
593             TextStoreHelper.GetStringExtent(this.Document, this._View, i_startIndex, i_endIndex, out startPos, out endPos);
594
595             double scale = this.Render.GetScale();
596             
597             startPos = PointToScreen(this.TranslatePoint(startPos.Scale(scale), this));
598             endPos = PointToScreen(this.TranslatePoint(endPos.Scale(scale), this));
599             
600             o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);
601             o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);
602         }
603
604         void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)
605         {
606             var pointTopLeft = new Point(0, 0);
607             var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
608
609             pointTopLeft = PointToScreen(pointTopLeft);
610             pointBottomRight = PointToScreen(pointBottomRight);
611
612             o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);
613             o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);
614         }
615
616         void _textStore_GetSelectionIndex(int start_index, int max_count, out DotNetTextStore.TextSelection[] sels)
617         {
618             TextRange selRange;
619             TextStoreHelper.GetSelection(this._Controller, this._View.Selections, out selRange);
620
621             sels = new DotNetTextStore.TextSelection[1];
622             sels[0] = new DotNetTextStore.TextSelection();
623             sels[0].start = selRange.Index;
624             sels[0].end = selRange.Index + selRange.Length;
625         }
626
627         void _textStore_SetSelectionIndex(DotNetTextStore.TextSelection[] sels)
628         {
629             TextStoreHelper.SetSelectionIndex(this._Controller, this._View, sels[0].start, sels[0].end);
630             this.Refresh();
631         }
632
633         void _textStore_InsertAtSelection(string i_value, ref int o_startIndex, ref int o_endIndex)
634         {
635             TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);
636             this.Refresh();
637         }
638
639         /// <summary>
640         /// キーボードフォーカスが取得されたときに呼ばれます
641         /// </summary>
642         /// <param name="e">イベントデーター</param>
643         protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
644         {
645             base.OnGotKeyboardFocus(e);
646             this.textStore.SetFocus();
647             this._View.IsFocused = true;
648             this.timer.Interval = new TimeSpan(0,0,0,0,Interval);
649             this.Refresh();
650         }
651
652         /// <summary>
653         /// キーボードフォーカスが失われたときに呼ばれます
654         /// </summary>
655         /// <param name="e">イベントデーター</param>
656         protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
657         {
658             base.OnLostKeyboardFocus(e);
659             this._View.IsFocused = false;
660             this.timer.Interval = new TimeSpan(0, 0, 0, 0, IntervalWhenLostFocuse);
661             this.Refresh();
662         }
663         #endregion
664         #region Event
665         /// <summary>
666         /// キャレットが移動したときに通知されるイベント
667         /// </summary>
668         public event EventHandler CaretMoved;
669
670         /// <inheritdoc/>
671         protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
672         {
673             this.peer = new FooTextBoxAutomationPeer(this);
674             return this.peer;
675         }
676
677
678         /// <inheritdoc/>
679         protected override void OnTextInput(TextCompositionEventArgs e)
680         {
681             if (e.Text == "\r")
682             {
683                 this._Controller.DoEnterAction();
684             }
685             else if (e.Text == "\b")
686             {
687                 this._Controller.DoBackSpaceAction();
688             }
689             else
690             {
691                 if(this.IsInputString(e.Text))
692                     this._Controller.DoInputString(e.Text);
693             }
694             this.Refresh();
695             base.OnTextInput(e);
696             e.Handled = true;
697         }
698
699         bool IsInputString(string s)
700         {
701             foreach (char charCode in s)
702             {
703                 if ((0x20 <= charCode && charCode <= 0x7e)
704                     || 0x7f < charCode)
705                     return true;
706             }
707             return false;
708         }
709
710         /// <inheritdoc/>
711         protected override void OnKeyDown(KeyEventArgs e)
712         {
713             if (this.textStore.IsLocked())
714                 return;
715
716             ModifierKeys modiferKeys = e.KeyboardDevice.Modifiers;
717
718             var autocomplete = this.Document.AutoComplete as AutoCompleteBox;
719             if (autocomplete != null &&
720                 autocomplete.ProcessKeyDown(this,e, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift)))
721             {
722                 e.Handled = true;
723                 return;
724             }
725
726             bool movedCaret = false;
727             double alignedPage = (int)(this.Render.TextArea.Height / this.Render.emSize.Height) * this.Render.emSize.Height;
728             switch (e.Key)
729             {
730                 case Key.Up:
731                     this._Controller.MoveCaretVertical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
732                     this.Refresh();
733                     e.Handled = true;
734                     movedCaret = true;
735                     break;
736                 case Key.Down:
737                     this._Controller.MoveCaretVertical(+1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
738                     this.Refresh();
739                     e.Handled = true;
740                     movedCaret = true;
741                     break;
742                 case Key.Left:
743                     this._Controller.MoveCaretHorizontical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
744                     this.Refresh();
745                     e.Handled = true;
746                     movedCaret = true;
747                     break;
748                 case Key.Right:
749                     this._Controller.MoveCaretHorizontical(1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
750                     this.Refresh();
751                     e.Handled = true;
752                     movedCaret = true;
753                     break;
754                 case Key.PageUp:
755                     this._Controller.ScrollByPixel(ScrollDirection.Up, alignedPage, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), true);
756                     this.Refresh();
757                     movedCaret = true;
758                     break;
759                 case Key.PageDown:
760                     this._Controller.ScrollByPixel(ScrollDirection.Down, alignedPage, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), true);
761                     this.Refresh();
762                     movedCaret = true;
763                     break;
764                 case Key.Home:
765                     if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
766                         this._Controller.JumpToHead(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
767                     else
768                         this._Controller.JumpToLineHead(this.Document.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
769                     this.Refresh();
770                     movedCaret = true;
771                     break;
772                 case Key.End:
773                     if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
774                         this._Controller.JumpToEnd(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
775                     else
776                         this._Controller.JumpToLineEnd(this.Document.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
777                     this.Refresh();
778                     movedCaret = true;
779                     break;
780                 case Key.Tab:
781                     int oldLength = this.Document.Length;
782                     if (this.Selection.Length == 0)
783                         this._Controller.DoInputChar('\t');
784                     else if(this.IsPressedModifierKey(modiferKeys,ModifierKeys.Shift))
785                         this._Controller.DownIndent();
786                     else
787                         this._Controller.UpIndent();
788                     this.Refresh();
789                     e.Handled = true;
790                     break;
791             }
792             if (movedCaret && this.peer != null)
793                 this.peer.OnNotifyCaretChanged();
794             base.OnKeyDown(e);
795         }
796
797         bool IsPressedModifierKey(ModifierKeys keys, ModifierKeys pressed)
798         {
799             if (keys == pressed)
800                 return true;
801             if ((keys & pressed) == pressed)
802                 return true;
803             return false;
804         }
805
806         /// <summary>
807         /// ダブルクリックされたときに呼ばれます
808         /// </summary>
809         /// <param name="e">イベントパラメーター</param>
810         /// <remarks>
811         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
812         /// e.Handledを真にした場合、単語単位の選択が行われなくなります
813         /// </remarks>
814         protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
815         {
816             var p = this.GetDipFromPoint(e.GetPosition(this));
817             TextPoint tp = this._View.GetTextPointFromPostion(p);
818             if (tp == TextPoint.Null)
819                 return;
820             int index = this._View.LayoutLines.GetIndexFromTextPoint(tp);
821
822             FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
823                 e.Timestamp,
824                 e.ChangedButton,
825                 e.StylusDevice,
826                 index);
827             newEventArgs.RoutedEvent = e.RoutedEvent;
828             base.OnMouseDoubleClick(newEventArgs);
829
830             if (newEventArgs.Handled)
831                 return;
832
833             if (e.LeftButton == MouseButtonState.Pressed)
834             {
835                 if (p.X < this.Render.TextArea.X)
836                     this.Document.SelectLine((int)index);
837                 else
838                     this.Document.SelectWord((int)index);
839
840                 this.textStore.NotifySelectionChanged();
841                 if(this.peer != null)
842                     this.peer.OnNotifyCaretChanged();
843                 this.Refresh();
844             }
845         }
846
847         /// <summary>
848         /// マウスボタンが押されたときに呼ばれます
849         /// </summary>
850         /// <param name="e">イベントパラメーター</param>
851         /// <remarks>
852         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
853         /// e.Handledを真にした場合、キャレットの移動処理が行われなくなります
854         /// </remarks>
855         protected override void OnMouseDown(MouseButtonEventArgs e)
856         {
857             this.CaptureMouse();
858
859             var p = this.GetDipFromPoint(e.GetPosition(this));
860             TextPoint tp = this._View.GetTextPointFromPostion(p);
861             if (tp == TextPoint.Null)
862                 return;
863             int index = this._View.LayoutLines.GetIndexFromTextPoint(tp);
864
865             FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
866                 e.Timestamp,
867                 e.ChangedButton,
868                 e.StylusDevice,
869                 index);
870             newEventArgs.RoutedEvent = e.RoutedEvent;
871             base.OnMouseDown(newEventArgs);
872
873             if (newEventArgs.Handled)
874                 return;
875
876             if (e.LeftButton == MouseButtonState.Pressed)
877             {
878                 FoldingItem foldingData = this._View.HitFoldingData(p.X,tp.row);
879                 if (foldingData != null)
880                 {
881                     if (foldingData.Expand)
882                         this._View.LayoutLines.FoldingCollection.Collapse(foldingData);
883                     else
884                         this._View.LayoutLines.FoldingCollection.Expand(foldingData);
885                     this._Controller.JumpCaret(foldingData.Start,false);
886                 }
887                 else
888                 {
889                     this._Controller.JumpCaret(tp.row, tp.col, false);
890                 }
891                 if (this.peer != null)
892                     this.peer.OnNotifyCaretChanged();
893                 this._View.IsFocused = true;
894                 this.Focus();
895                 this.Document.SelectGrippers.BottomLeft.Enabled = false;
896                 this.Document.SelectGrippers.BottomRight.Enabled = false;
897                 this.Refresh();
898             }
899         }
900
901         /// <summary>
902         /// マウスのボタンが離されたときに呼ばれます
903         /// </summary>
904         /// <param name="e"></param>
905         protected override void OnMouseUp(MouseButtonEventArgs e)
906         {
907             this.ReleaseMouseCapture();
908             base.OnMouseUp(e);
909         }
910
911         /// <summary>
912         /// マウスが移動したときに呼ばれます
913         /// </summary>
914         /// <param name="e">イベントパラメーター</param>
915         /// <remarks>
916         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
917         /// e.Handledを真にした場合、選択処理と状況に応じたカーソルの変化が行われなくなります
918         /// </remarks>
919         protected override void  OnMouseMove(MouseEventArgs e)
920         {
921             bool leftPressed = e.LeftButton == MouseButtonState.Pressed;
922
923             var p = this.GetDipFromPoint(e.GetPosition(this));
924
925             TextPointSearchRange searchRange;
926             if (this._View.HitTextArea(p.X, p.Y))
927             {
928                 searchRange = TextPointSearchRange.TextAreaOnly;
929             }
930             else if (leftPressed)
931             {
932                 searchRange = TextPointSearchRange.Full;
933             }
934             else
935             {
936                 this.Cursor = Cursors.Arrow;
937                 base.OnMouseMove(e);
938                 return;
939             }
940
941             TextPoint tp = this._View.GetTextPointFromPostion(p, searchRange);
942
943             if (tp == TextPoint.Null)
944             {
945                 this.Cursor = Cursors.Arrow;
946                 base.OnMouseMove(e);
947                 return;
948             }
949
950             int index = this._View.GetIndexFromLayoutLine(tp);
951
952             FooMouseEventArgs newEventArgs = new FooMouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice, index);
953             newEventArgs.RoutedEvent = e.RoutedEvent;
954             base.OnMouseMove(newEventArgs);
955
956             if (newEventArgs.Handled)
957                 return;
958
959             //この状態のときはカーソルがテキストエリア内にある
960             if (searchRange == TextPointSearchRange.TextAreaOnly)
961             {
962                 if (this._Controller.IsMarker(tp, HilightType.Url))
963                     this.Cursor = Cursors.Hand;
964                 else
965                     this.Cursor = Cursors.IBeam;
966             }
967             else
968             {
969                 this.Cursor = Cursors.Arrow;
970             }
971
972             //スクロールバーを押した場合はキャレットを移動させる必要がない
973             if (leftPressed && e.OriginalSource.GetType() == typeof(FooTextBox))
974             {
975                 bool controlPressed = (Keyboard.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) == KeyStates.Down;
976                 this._Controller.MoveCaretAndSelect(tp, controlPressed);
977                 if (this.peer != null)
978                     this.peer.OnNotifyCaretChanged();
979                 this.Refresh();
980             }
981         }
982
983         Gripper hittedGripper;
984         bool touchScrolled = false;
985
986         /// <inheritdoc/>
987         protected override void OnTouchDown(TouchEventArgs e)
988         {
989             var p = this.GetDipFromPoint(e.GetTouchPoint(this).Position);
990             this.hittedGripper = this._View.HitGripperFromPoint(p);
991             this.CaptureTouch(e.TouchDevice);
992         }
993
994         /// <inheritdoc/>
995         protected override void OnTouchUp(TouchEventArgs e)
996         {
997             this.ReleaseTouchCapture(e.TouchDevice);
998             if(this.hittedGripper != null || this.touchScrolled)
999             {
1000                 this.hittedGripper = null;
1001                 this.touchScrolled = false;
1002                 return;
1003             }
1004
1005             var p = this.GetDipFromPoint(e.GetTouchPoint(this).Position);
1006             TextPoint tp = this._View.GetTextPointFromPostion(p);
1007             if (tp == TextPoint.Null)
1008                 return;
1009             int index = this._View.LayoutLines.GetIndexFromTextPoint(tp);
1010
1011             FoldingItem foldingData = this._View.HitFoldingData(p.X, tp.row);
1012             if (foldingData != null)
1013             {
1014                 if (foldingData.Expand)
1015                     this._View.LayoutLines.FoldingCollection.Collapse(foldingData);
1016                 else
1017                     this._View.LayoutLines.FoldingCollection.Expand(foldingData);
1018                 this._Controller.JumpCaret(foldingData.Start, false);
1019             }
1020             else
1021             {
1022                 this._Controller.JumpCaret(tp.row, tp.col, false);
1023             }
1024             if (this.peer != null)
1025                 this.peer.OnNotifyCaretChanged();
1026             this._View.IsFocused = true;
1027             this.Focus();
1028             this.Document.SelectGrippers.BottomLeft.Enabled = false;
1029             this.Document.SelectGrippers.BottomRight.Enabled = true;
1030             this.Refresh();
1031         }
1032
1033         /// <inheritdoc/>
1034         protected override void OnTouchMove(TouchEventArgs e)
1035         {
1036             var p = this.GetDipFromPoint(e.GetTouchPoint(this).Position);
1037             if (this.Controller.MoveCaretAndGripper(p, this.hittedGripper))
1038             {
1039                 if (this.peer != null)
1040                     this.peer.OnNotifyCaretChanged();
1041                 this.Refresh();
1042             }
1043         }
1044
1045         /// <inheritdoc/>
1046         protected override void OnManipulationInertiaStarting(ManipulationInertiaStartingEventArgs e)
1047         {
1048         }
1049
1050         /// <inheritdoc/>
1051         protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
1052         {
1053             if (this.hittedGripper != null)
1054                 return;
1055
1056             Point translation = new Point(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);
1057
1058             //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい
1059             if (Math.Abs(e.CumulativeManipulation.Translation.X) < Math.Abs(e.CumulativeManipulation.Translation.Y))
1060             {
1061                 int deltay = (int)Math.Abs(Math.Ceiling(translation.Y));
1062                 if (translation.Y < 0)
1063                     this._Controller.ScrollByPixel(ScrollDirection.Down, deltay, false, false);
1064                 else
1065                     this._Controller.ScrollByPixel(ScrollDirection.Up, deltay, false, false);
1066                 this.touchScrolled = true;
1067                 this.Refresh();
1068                 return;
1069             }
1070
1071             int deltax = (int)Math.Abs(Math.Ceiling(translation.X));
1072             if (deltax != 0)
1073             {
1074                 if (translation.X < 0)
1075                     this._Controller.Scroll(ScrollDirection.Left, deltax, false, false);
1076                 else
1077                     this._Controller.Scroll(ScrollDirection.Right, deltax, false, false);
1078                 this.touchScrolled = true;
1079                 this.Refresh();
1080             }
1081         }
1082
1083         private Point GetDipFromPoint(Point p)
1084         {
1085             float dpi;
1086             this.Render.GetDpi(out dpi,out dpi);
1087             double scale = dpi / 96.0;
1088             return p.Scale(1 / scale);
1089         }
1090
1091         /// <inheritdoc/>
1092         protected override void OnMouseWheel(MouseWheelEventArgs e)
1093         {
1094             if(Keyboard.Modifiers == ModifierKeys.None)
1095             {
1096                 if (e.Delta > 0)
1097                     this._Controller.Scroll(ScrollDirection.Up, SystemParameters.WheelScrollLines, false, false);
1098                 else
1099                     this._Controller.Scroll(ScrollDirection.Down, SystemParameters.WheelScrollLines, false, false);
1100             }
1101             else if (Keyboard.Modifiers == ModifierKeys.Control)
1102             {
1103                 double newFontSize = this.Render.FontSize;
1104                 if (e.Delta > 0)
1105                     newFontSize++;
1106                 else
1107                     newFontSize--;
1108                 if (newFontSize > MaxFontSize)
1109                     newFontSize = 72;
1110                 else if (newFontSize < MinFontSize)
1111                     newFontSize = 1;
1112                 this.Render.FontSize = newFontSize;
1113                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
1114             }
1115             this.Refresh();
1116             base.OnMouseWheel(e);
1117         }
1118
1119         void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
1120         {
1121             if (e.Category == UserPreferenceCategory.Keyboard)
1122             {
1123                 int blinkTime = (int)NativeMethods.GetCaretBlinkTime();
1124                 this._View.CaretBlink = blinkTime >= 0;
1125                 this._View.CaretBlinkTime = blinkTime * 2;
1126             }
1127             if (e.Category == UserPreferenceCategory.General)
1128             {
1129                 this._View.CaretWidthOnInsertMode = SystemParameters.CaretWidth;
1130             }
1131         }
1132
1133         void Document_Update(object sender, DocumentUpdateEventArgs e)
1134         {
1135             if (this.textStore.IsLocked())
1136                 return;
1137             if(e.type == UpdateType.Replace)
1138                 TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);
1139             if(this.peer != null)
1140                 this.peer.OnNotifyTextChanged();
1141         }
1142
1143         void timer_Tick(object sender, EventArgs e)
1144         {
1145             if (this.image.ActualWidth == 0 || this.image.ActualHeight == 0)
1146                 return;
1147             if (this.Resize(this.image.ActualWidth, this.image.ActualHeight))
1148             {
1149                 this.Refresh(this._View.PageBound);
1150                 return;
1151             }
1152
1153             bool updateAll = this._View.LayoutLines.HilightAll() || this._View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw;
1154
1155             if (updateAll)
1156                 this.Refresh(this._View.PageBound);
1157             else
1158                 this.Refresh(this._View.GetCurrentCaretRect());
1159         }
1160
1161         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
1162         {
1163             if (this.horizontalScrollBar == null)
1164                 return;
1165             double toX;
1166             if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
1167                 toX = this.horizontalScrollBar.Value;
1168             else
1169                 toX = -this.horizontalScrollBar.Value;
1170             this.Controller.ScrollByPixel(ScrollDirection.Left, (int)toX, false, false);
1171             this.Refresh();
1172         }
1173
1174         void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
1175         {
1176             if (this.verticalScrollBar == null)
1177                 return;
1178             this.Controller.Scroll(this.Document.Src.X, (int)this.verticalScrollBar.Value, false, false);
1179             this.Refresh();
1180         }
1181
1182         void View_SrcChanged(object sender, EventArgs e)
1183         {
1184             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
1185                 return;
1186             EditView view = this._View;
1187             if (view.Src.Row > this.Document.LayoutLines.Count)
1188                 this.verticalScrollBar.Maximum = this.Document.LayoutLines.Count - 1;
1189             double absoulteX = Math.Abs(view.Src.X);
1190             if(absoulteX > this.horizontalScrollBar.Maximum)
1191                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
1192             if(view.Src.Row != this.verticalScrollBar.Value)
1193                 this.verticalScrollBar.Value = view.Src.Row;
1194             if (view.Src.X != this.horizontalScrollBar.Value)
1195                 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
1196         }
1197
1198         void Controller_SelectionChanged(object sender, EventArgs e)
1199         {
1200             this._View.CaretBlink = this._View.CaretBlink;
1201             this.CaretMoved(this, null);
1202             //こうしないと選択できなくなってしまう
1203             this.isNotifyChanged = true;
1204             SetValue(SelectedTextProperty, this._Controller.SelectedText);
1205             SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
1206             SetValue(CaretPostionProperty, this.Document.CaretPostion);
1207             this.isNotifyChanged = false;
1208             if (this.textStore.IsLocked() == false)
1209                 this.textStore.NotifySelectionChanged();
1210         }
1211
1212         void FooTextBox_Loaded(object sender, RoutedEventArgs e)
1213         {
1214             this.Resize(this.image.ActualWidth, this.image.ActualHeight);
1215             this.Focus();
1216             this.timer.Start();
1217         }
1218
1219         bool Resize(double width, double height)
1220         {
1221             if (width == 0 || height == 0)
1222                 throw new ArgumentOutOfRangeException();
1223             if (this.Render.Resize(width, height))
1224             {
1225                 double scale = this.Render.GetScale();
1226                 // RenderはレタリングはDIPだが、widthとheightの値はDPI依存なのでDIPに変換する
1227                 this._View.PageBound = new Rectangle(0, 0, width / scale, height / scale);
1228
1229                 if (this.horizontalScrollBar != null)
1230                 {
1231                     this.horizontalScrollBar.LargeChange = this._View.PageBound.Width;
1232                     this.horizontalScrollBar.Maximum = this._View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
1233                 }
1234                 if (this.verticalScrollBar != null)
1235                 {
1236                     this.verticalScrollBar.LargeChange = this._View.LineCountOnScreen;
1237                     this.verticalScrollBar.Maximum = this._View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
1238                 }
1239                 return true;
1240             }
1241             return false;
1242         }
1243
1244         private void SetDocument(Document value)
1245         {
1246             if (value == null)
1247                 return;
1248
1249             Document old_doc = this._Document;
1250             int oldLength = 0;
1251             if (this._Document != null)
1252             {
1253                 old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
1254                 old_doc.LoadProgress -= Document_LoadProgress;
1255                 old_doc.SelectionChanged -= new EventHandler(Controller_SelectionChanged);
1256                 old_doc.AutoCompleteChanged -= _Document_AutoCompleteChanged;
1257                 oldLength = old_doc.Length;
1258                 if (this._Document.AutoComplete != null)
1259                 {
1260                     ((AutoCompleteBox)this._Document.AutoComplete).TargetPopup = null;
1261                     this._Document.AutoComplete.GetPostion = null;
1262                     this._Document.AutoComplete = null;
1263                 }
1264             }
1265
1266             this._Document = value;
1267             this._Document.LayoutLines.Render = this.Render;
1268             this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
1269             this._Document.LoadProgress += Document_LoadProgress;
1270             this._Document.AutoCompleteChanged += _Document_AutoCompleteChanged;
1271             if (this._Document.AutoComplete != null && this.Document.AutoComplete.GetPostion == null)
1272                 this._Document_AutoCompleteChanged(this.Document, null);
1273             //初期化が終わっていればすべて存在する
1274             if (this.Controller != null && this._View != null && this.textStore != null)
1275             {
1276                 this._Document.SelectionChanged += new EventHandler(Controller_SelectionChanged);
1277
1278                 this.Controller.Document = value;
1279                 this._View.Document = value;
1280                 this.Controller.AdjustCaret();
1281                 this.textStore.NotifyTextChanged(oldLength, value.Length);
1282
1283                 //依存プロパティとドキュメント内容が食い違っているので再設定する
1284                 this.ShowFullSpace = value.ShowFullSpace;
1285                 this.ShowHalfSpace = value.ShowHalfSpace;
1286                 this.ShowLineBreak = value.ShowLineBreak;
1287                 this.ShowTab = value.ShowTab;
1288                 this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
1289                 this.IndentMode = value.IndentMode;
1290                 this.DrawCaretLine = !value.HideLineMarker;
1291                 this.InsertMode = value.InsertMode;
1292                 this.DrawRuler = !value.HideRuler;
1293                 this.DrawLineNumber = value.DrawLineNumber;
1294                 this.MarkURL = value.UrlMark;
1295                 this.LineBreakMethod = value.LineBreak;
1296                 this.LineBreakCharCount = value.LineBreakCharCount;
1297                 this.TabChars = value.TabStops;
1298
1299                 this.Refresh();
1300             }
1301         }
1302
1303         private void _Document_AutoCompleteChanged(object sender, EventArgs e)
1304         {
1305             Document doc = (Document)sender;
1306             ((AutoCompleteBox)this._Document.AutoComplete).TargetPopup = this.popup;
1307             this._Document.AutoComplete.GetPostion = (tp, edoc) =>
1308             {
1309                 var p = this._View.GetPostionFromTextPoint(tp);
1310                 int height = (int)this.Render.emSize.Height;
1311                 p.Y += height;
1312                 return PointToScreen(this.TranslatePoint(p.Scale(Util.GetScale()), this));
1313             };
1314         }
1315
1316         /// <summary>
1317         /// プロパティーが変更されたときに呼ばれます
1318         /// </summary>
1319         /// <param name="e">イベントパラメーター</param>
1320         protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
1321         {
1322             switch (e.Property.Name)
1323             {
1324                 case "Document":
1325                     this.SetDocument(this.Document);
1326                     break;
1327                 case "Hilighter":
1328                     this._View.Hilighter = this.Hilighter;
1329                     break;
1330                 case "TextAntialiasMode":
1331                     this.Render.TextAntialiasMode = this.TextAntialiasMode;
1332                     break;
1333                 case "FoldingStrategy":
1334                     this._View.LayoutLines.FoldingStrategy = this.FoldingStrategy;
1335                     break;
1336                 case "SelectedText":
1337                     if (!this.isNotifyChanged)
1338                         this._Controller.SelectedText = this.SelectedText;
1339                     break;
1340                 case "IndentMode":
1341                     this._Controller.IndentMode = this.IndentMode;
1342                     break;
1343                 case "Selection":
1344                     if(!this.isNotifyChanged)
1345                         this.Select(this.Selection.Index, this.Selection.Length);
1346                     break;
1347                 case "CaretPostion":
1348                     if (!this.isNotifyChanged)
1349                         this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);
1350                     break;
1351                 case "LineBreakMethod":
1352                     this.Document.LineBreak = this.LineBreakMethod;
1353                     break;
1354                 case "LineBreakCharCount":
1355                     this.Document.LineBreakCharCount = this.LineBreakCharCount;
1356                     break;
1357                 case "InsertMode":
1358                     this._View.InsertMode = this.InsertMode;
1359                     break;
1360                 case "TabChars":
1361                     this.Document.TabStops = this.TabChars;
1362                     break;
1363                 case "RectSelectMode":
1364                     this._Controller.RectSelection = this.RectSelectMode;
1365                     break;
1366                 case "DrawCaret":
1367                     this._View.HideCaret = !this.DrawCaret;
1368                     break;
1369                 case "DrawCaretLine":
1370                     this._View.HideLineMarker = !this.DrawCaretLine;
1371                     break;
1372                 case "DrawLineNumber":
1373                     this.Document.DrawLineNumber = this.DrawLineNumber;
1374                     break;
1375                 case "FontFamily":
1376                     this.Render.FontFamily = this.FontFamily;
1377                     break;
1378                 case "FontSize":
1379                     this.Render.FontSize = this.FontSize;
1380                     break;
1381                 case "FontStyle":
1382                     this.Render.FontStyle = this.FontStyle;
1383                     break;
1384                 case "FontWeight":
1385                     this.Render.FontWeigth = this.FontWeight;
1386                     break;
1387                 case "Foreground":
1388                     this.Render.Foreground = D2DRender.ToColor4(this.Foreground);
1389                     break;
1390                 case "HilightForeground":
1391                     this.Render.HilightForeground = D2DRender.ToColor4(this.HilightForeground);
1392                     break;
1393                 case "Background":
1394                     this.Render.Background = D2DRender.ToColor4(this.Background);
1395                     break;
1396                 case "ControlChar":
1397                     this.Render.ControlChar =D2DRender.ToColor4( this.ControlChar);
1398                     break;
1399                 case "Hilight":
1400                     this.Render.Hilight = D2DRender.ToColor4(this.Hilight);
1401                     break;
1402                 case "Keyword1":
1403                     this.Render.Keyword1 = D2DRender.ToColor4(this.Keyword1);
1404                     break;
1405                 case "Keyword2":
1406                     this.Render.Keyword2 = D2DRender.ToColor4(this.Keyword2);
1407                     break;
1408                 case "Comment":
1409                     this.Render.Comment = D2DRender.ToColor4(this.Comment);
1410                     break;
1411                 case "Literal":
1412                     this.Render.Literal = D2DRender.ToColor4(this.Literal);
1413                     break;
1414                 case "URL":
1415                     this.Render.Url = D2DRender.ToColor4(this.URL);
1416                     break;
1417                 case "InsertCaret":
1418                     this.Render.InsertCaret = D2DRender.ToColor4(this.InsertCaret);
1419                     break;
1420                 case "OverwriteCaret":
1421                     this.Render.OverwriteCaret = D2DRender.ToColor4(this.OverwriteCaret);
1422                     break;
1423                 case "Padding":
1424                     this._View.Padding = new Padding((int)this.Padding.Left, (int)this.Padding.Top, (int)this.Padding.Right, (int)this.Padding.Bottom);
1425                     break;
1426                 case "LineMarker":
1427                     this.Render.LineMarker = D2DRender.ToColor4(this.LineMarker);
1428                     break;
1429                 case "MarkURL":
1430                     this.Document.UrlMark = this.MarkURL;
1431                     break;
1432                 case "ShowFullSpace":
1433                     this.Document.ShowFullSpace = this.ShowFullSpace;
1434                     break;
1435                 case "ShowHalfSpace":
1436                     this.Document.ShowHalfSpace = this.ShowHalfSpace;
1437                     break;
1438                 case "ShowTab":
1439                     this.Document.ShowTab = this.ShowTab;
1440                     break;
1441                 case "ShowLineBreak":
1442                     this.Document.ShowLineBreak = this.ShowLineBreak;
1443                     break;
1444                 case "FlowDirection":
1445                     this.Document.RightToLeft = this.FlowDirection == System.Windows.FlowDirection.RightToLeft;
1446                     this.horizontalScrollBar.FlowDirection = this.FlowDirection;
1447                     break;
1448                 case "DrawRuler":
1449                     this.Document.HideRuler = !this.DrawRuler;
1450                     this._Controller.JumpCaret(this.Document.CaretPostion.row, this.Document.CaretPostion.col);
1451                     break;
1452                 case "UpdateArea":
1453                     this.Render.UpdateArea = D2DRender.ToColor4(this.UpdateArea);
1454                     break;
1455                 case "LineNumber":
1456                     this.Render.LineNumber = D2DRender.ToColor4(this.LineNumber);
1457                     break;
1458             }
1459             base.OnPropertyChanged(e);
1460         }
1461         #endregion
1462         #region property
1463
1464         internal EditView View
1465         {
1466             get
1467             {
1468                 return this._View;
1469             }
1470         }
1471
1472         internal Controller Controller
1473         {
1474             get
1475             {
1476                 return this._Controller;
1477             }
1478         }
1479
1480         /// <summary>
1481         /// 文字列の描写に使用されるアンチエイリアシング モードを表します
1482         /// </summary>
1483         public TextAntialiasMode TextAntialiasMode
1484         {
1485             get { return (TextAntialiasMode)GetValue(TextAntialiasModeProperty); }
1486             set { SetValue(TextAntialiasModeProperty, value); }
1487         }
1488
1489         /// <summary>
1490         /// TextAntialiasModeの依存プロパティを表す
1491         /// </summary>
1492         public static readonly DependencyProperty TextAntialiasModeProperty =
1493             DependencyProperty.Register("TextAntialiasMode", typeof(TextAntialiasMode), typeof(FooTextBox), new PropertyMetadata(TextAntialiasMode.Default));
1494
1495         /// <summary>
1496         /// シンタックスハイライターを表す
1497         /// </summary>
1498         public IHilighter Hilighter
1499         {
1500             get { return (IHilighter)GetValue(HilighterProperty); }
1501             set { SetValue(HilighterProperty, value); }
1502         }
1503
1504         /// <summary>
1505         /// Hilighterの依存プロパティを表す
1506         /// </summary>
1507         public static readonly DependencyProperty HilighterProperty =
1508             DependencyProperty.Register("Hilighter", typeof(IHilighter), typeof(FooTextBox), new PropertyMetadata(null));
1509
1510         /// <summary>
1511         /// フォールティングを作成するインターフェイスを表す
1512         /// </summary>
1513         public IFoldingStrategy FoldingStrategy
1514         {
1515             get { return (IFoldingStrategy)GetValue(FoldingStrategyProperty); }
1516             set { SetValue(FoldingStrategyProperty, value); }
1517         }
1518
1519         /// <summary>
1520         /// FoldingStrategyの依存プロパティ
1521         /// </summary>
1522         public static readonly DependencyProperty FoldingStrategyProperty =
1523             DependencyProperty.Register("FoldingStrategy", typeof(IFoldingStrategy), typeof(FooTextBox), new PropertyMetadata(null));
1524
1525
1526         /// <summary>
1527         /// マーカーパターンセット
1528         /// </summary>
1529         public MarkerPatternSet MarkerPatternSet
1530         {
1531             get
1532             {
1533                 return this.Document.MarkerPatternSet;
1534             }
1535         }
1536
1537         /// <summary>
1538         /// ドキュメント表す
1539         /// </summary>
1540         public Document Document
1541         {
1542             get { return (Document)GetValue(DocumentProperty); }
1543             set { SetValue(DocumentProperty, value); }
1544         }
1545
1546         /// <summary>
1547         /// ドキュメント添付プロパティ
1548         /// </summary>
1549         public static readonly DependencyProperty DocumentProperty =
1550             DependencyProperty.Register("Document", typeof(Document), typeof(FooTextBox), new PropertyMetadata(null));
1551
1552
1553         /// <summary>
1554         /// レイアウト行を表す
1555         /// </summary>
1556         public LineToIndexTable LayoutLineCollection
1557         {
1558             get { return this._View.LayoutLines; }
1559         }
1560
1561         /// <summary>
1562         /// 選択中の文字列を表す
1563         /// </summary>
1564         public string SelectedText
1565         {
1566             get { return (string)GetValue(SelectedTextProperty); }
1567             set { SetValue(SelectedTextProperty, value); }
1568         }
1569
1570         /// <summary>
1571         /// SelectedTextの依存プロパティを表す
1572         /// </summary>
1573         public static readonly DependencyProperty SelectedTextProperty =
1574             DependencyProperty.Register("SelectedText", typeof(string), typeof(FooTextBox), new PropertyMetadata(null));
1575
1576         /// <summary>
1577         /// インデントの方法を表す
1578         /// </summary>
1579         public IndentMode IndentMode
1580         {
1581             get { return (IndentMode)GetValue(IndentModeProperty); }
1582             set { SetValue(IndentModeProperty, value); }
1583         }
1584
1585         /// <summary>
1586         /// IndentModeの依存プロパティを表す
1587         /// </summary>
1588         public static readonly DependencyProperty IndentModeProperty =
1589             DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab));
1590
1591         /// <summary>
1592         /// 選択範囲を表す
1593         /// </summary>
1594         /// <remarks>
1595         /// Lengthが0の場合はキャレット位置を表します。
1596         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
1597         /// </remarks>
1598         public TextRange Selection
1599         {
1600             get { return (TextRange)GetValue(SelectionProperty); }
1601             set { SetValue(SelectionProperty, value); }
1602         }
1603
1604         /// <summary>
1605         /// Selectionの依存プロパティを表す
1606         /// </summary>
1607         public static readonly DependencyProperty SelectionProperty =
1608             DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null));
1609
1610         /// <summary>
1611         /// 拡大率を表す
1612         /// </summary>
1613         public double MagnificationPower
1614         {
1615             get { return (double)GetValue(MagnificationPowerPropertyKey.DependencyProperty); }
1616         }
1617
1618         /// <summary>
1619         /// 拡大率を表す依存プロパティ
1620         /// </summary>
1621         public static readonly DependencyPropertyKey MagnificationPowerPropertyKey =
1622             DependencyProperty.RegisterReadOnly("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0));
1623
1624         /// <summary>
1625         /// レタリング方向を表す
1626         /// </summary>
1627         public new FlowDirection FlowDirection
1628         {
1629             get { return (FlowDirection)GetValue(FlowDirectionProperty); }
1630             set { SetValue(FlowDirectionProperty, value); }
1631         }
1632
1633         /// <summary>
1634         /// レタリング方向を表す。これは依存プロパティです
1635         /// </summary>
1636         public new static readonly DependencyProperty FlowDirectionProperty =
1637             DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight));        
1638
1639         /// <summary>
1640         /// キャレット位置を表す。これは依存プロパティです
1641         /// </summary>
1642         public TextPoint CaretPostion
1643         {
1644             get { return (TextPoint)GetValue(CaretPostionProperty); }
1645             set { SetValue(CaretPostionProperty, value); }
1646         }
1647
1648         /// <summary>
1649         /// CaretPostionの依存プロパティを表す
1650         /// </summary>
1651         public static readonly DependencyProperty CaretPostionProperty =
1652             DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(TextPoint.Null));
1653         
1654         /// <summary>
1655         /// デフォルトの文字色を表す。これは依存プロパティです
1656         /// </summary>
1657         public new System.Windows.Media.Color Foreground
1658         {
1659             get { return (System.Windows.Media.Color)GetValue(ForegroundProperty); }
1660             set { SetValue(ForegroundProperty, value); }
1661         }
1662
1663         /// <summary>
1664         /// Foregroundの依存プロパティを表す
1665         /// </summary>
1666         public new static readonly DependencyProperty ForegroundProperty =
1667             DependencyProperty.Register("Foreground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1668
1669         /// <summary>
1670         /// 背景色を表す。これは依存プロパティです
1671         /// </summary>
1672         public new System.Windows.Media.Color Background
1673         {
1674             get { return (System.Windows.Media.Color)GetValue(BackgroundProperty); }
1675             set { SetValue(BackgroundProperty, value); }
1676         }
1677
1678         /// <summary>
1679         /// Backgroundの依存プロパティを表す
1680         /// </summary>
1681         public new static readonly DependencyProperty BackgroundProperty =
1682             DependencyProperty.Register("Background", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowColor));
1683
1684         /// <summary>
1685         /// 選択時の文字色を表す。これは依存プロパティです
1686         /// </summary>
1687         public System.Windows.Media.Color HilightForeground
1688         {
1689             get { return (System.Windows.Media.Color)GetValue(HilightForegroundProperty); }
1690             set { SetValue(HilightForegroundProperty, value); }
1691         }
1692
1693         /// <summary>
1694         /// ControlCharの依存プロパティを表す
1695         /// </summary>
1696         public static readonly DependencyProperty HilightForegroundProperty =
1697             DependencyProperty.Register("HilightForeground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.White));
1698
1699         /// <summary>
1700         /// コントロールコードの文字色を表す。これは依存プロパティです
1701         /// </summary>
1702         public System.Windows.Media.Color ControlChar
1703         {
1704             get { return (System.Windows.Media.Color)GetValue(ControlCharProperty); }
1705             set { SetValue(ControlCharProperty, value); }
1706         }
1707
1708         /// <summary>
1709         /// ControlCharの依存プロパティを表す
1710         /// </summary>
1711         public static readonly DependencyProperty ControlCharProperty =
1712             DependencyProperty.Register("ControlChar", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Gray));
1713         
1714         /// <summary>
1715         /// 選択時の背景色を表す。これは依存プロパティです
1716         /// </summary>
1717         public System.Windows.Media.Color Hilight
1718         {
1719             get { return (System.Windows.Media.Color)GetValue(HilightProperty); }
1720             set { SetValue(HilightProperty, value); }
1721         }
1722
1723         /// <summary>
1724         /// Hilightの依存プロパティを表す
1725         /// </summary>
1726         public static readonly DependencyProperty HilightProperty =
1727             DependencyProperty.Register("Hilight", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DeepSkyBlue));
1728         
1729         /// <summary>
1730         /// キーワード1の文字色を表す。これは依存プロパティです
1731         /// </summary>
1732         public System.Windows.Media.Color Keyword1
1733         {
1734             get { return (System.Windows.Media.Color)GetValue(Keyword1Property); }
1735             set { SetValue(Keyword1Property, value); }
1736         }
1737
1738         /// <summary>
1739         /// Keyword1の依存プロパティを表す
1740         /// </summary>
1741         public static readonly DependencyProperty Keyword1Property =
1742             DependencyProperty.Register("Keyword1", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
1743
1744         /// <summary>
1745         /// キーワード2の文字色を表す。これは依存プロパティです
1746         /// </summary>
1747         public System.Windows.Media.Color Keyword2
1748         {
1749             get { return (System.Windows.Media.Color)GetValue(Keyword2Property); }
1750             set { SetValue(Keyword2Property, value); }
1751         }
1752
1753         /// <summary>
1754         /// Keyword2の依存プロパティを表す
1755         /// </summary>
1756         public static readonly DependencyProperty Keyword2Property =
1757             DependencyProperty.Register("Keyword2", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DarkCyan));
1758
1759         /// <summary>
1760         /// コメントの文字色を表す。これは依存プロパティです
1761         /// </summary>
1762         public System.Windows.Media.Color Comment
1763         {
1764             get { return (System.Windows.Media.Color)GetValue(CommentProperty); }
1765             set { SetValue(CommentProperty, value); }
1766         }
1767
1768         /// <summary>
1769         /// Commentの依存プロパティを表す
1770         /// </summary>
1771         public static readonly DependencyProperty CommentProperty =
1772             DependencyProperty.Register("Comment", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Green));
1773
1774         /// <summary>
1775         /// 文字リテラルの文字色を表す。これは依存プロパティです
1776         /// </summary>
1777         public System.Windows.Media.Color Literal
1778         {
1779             get { return (System.Windows.Media.Color)GetValue(LiteralProperty); }
1780             set { SetValue(LiteralProperty, value); }
1781         }
1782
1783         /// <summary>
1784         /// Literalの依存プロパティを表す
1785         /// </summary>
1786         public static readonly DependencyProperty LiteralProperty =
1787             DependencyProperty.Register("Literal", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Brown));
1788
1789         /// <summary>
1790         /// URLの文字色を表す。これは依存プロパティです
1791         /// </summary>
1792         public System.Windows.Media.Color URL
1793         {
1794             get { return (System.Windows.Media.Color)GetValue(URLProperty); }
1795             set { SetValue(URLProperty, value); }
1796         }
1797
1798         /// <summary>
1799         /// URLの依存プロパティを表す
1800         /// </summary>
1801         public static readonly DependencyProperty URLProperty =
1802             DependencyProperty.Register("URL", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
1803
1804
1805         /// <summary>
1806         /// ラインマーカーの色を表す
1807         /// </summary>
1808         public System.Windows.Media.Color LineMarker
1809         {
1810             get { return (System.Windows.Media.Color)GetValue(LineMarkerProperty); }
1811             set { SetValue(LineMarkerProperty, value); }
1812         }
1813
1814         /// <summary>
1815         /// LineMarkerの依存プロパティを表す
1816         /// </summary>
1817         public static readonly DependencyProperty LineMarkerProperty =
1818             DependencyProperty.Register("LineMarker", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Silver));
1819
1820         /// <summary>
1821         /// 挿入モード時のキャレットの色を表す
1822         /// </summary>
1823         public System.Windows.Media.Color InsertCaret
1824         {
1825             get { return (System.Windows.Media.Color)GetValue(InsertCaretProperty); }
1826             set { SetValue(InsertCaretProperty, value); }
1827         }
1828
1829         /// <summary>
1830         /// InsertCaretの依存プロパティを表す
1831         /// </summary>
1832         public static readonly DependencyProperty InsertCaretProperty =
1833             DependencyProperty.Register("InsertCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1834
1835         /// <summary>
1836         /// 行更新フラグの色を表す
1837         /// </summary>
1838         public System.Windows.Media.Color UpdateArea
1839         {
1840             get { return (System.Windows.Media.Color)GetValue(UpdateAreaProperty); }
1841             set { SetValue(UpdateAreaProperty, value); }
1842         }
1843
1844         /// <summary>
1845         /// UpdateAreaの依存プロパティを表す
1846         /// </summary>
1847         public static readonly DependencyProperty UpdateAreaProperty =
1848             DependencyProperty.Register("UpdateArea", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));        
1849
1850         /// <summary>
1851         /// 上書きモード時のキャレット職を表す
1852         /// </summary>
1853         public System.Windows.Media.Color OverwriteCaret
1854         {
1855             get { return (System.Windows.Media.Color)GetValue(OverwriteCaretProperty); }
1856             set { SetValue(OverwriteCaretProperty, value); }
1857         }
1858         
1859         /// <summary>
1860         /// OverwriteCaretの依存プロパティを表す
1861         /// </summary>
1862         public static readonly DependencyProperty OverwriteCaretProperty =
1863             DependencyProperty.Register("OverwriteCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1864
1865         /// <summary>
1866         /// 行番号の色を表す
1867         /// </summary>
1868         public System.Windows.Media.Color LineNumber
1869         {
1870             get { return (System.Windows.Media.Color)GetValue(LineNumberProperty); }
1871             set { SetValue(LineNumberProperty, value); }
1872         }
1873
1874         /// <summary>
1875         /// Using a DependencyProperty as the backing store for LineNumber.  This enables animation, styling, binding, etc...
1876         /// </summary>
1877         public static readonly DependencyProperty LineNumberProperty =
1878             DependencyProperty.Register("LineNumber", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray));
1879
1880         /// <summary>
1881         /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
1882         /// </summary>
1883         public bool InsertMode
1884         {
1885             get { return (bool)GetValue(InsertModeProperty); }
1886             set { SetValue(InsertModeProperty, value); }
1887         }
1888
1889         /// <summary>
1890         /// InsertModeの依存プロパティを表す
1891         /// </summary>
1892         public static readonly DependencyProperty InsertModeProperty =
1893             DependencyProperty.Register("InsertMode",
1894             typeof(bool),
1895             typeof(FooTextBox),
1896             new FrameworkPropertyMetadata(true));
1897
1898         /// <summary>
1899         /// タブの文字数を表す。これは依存プロパティです
1900         /// </summary>
1901         public int TabChars
1902         {
1903             get { return (int)GetValue(TabCharsProperty); }
1904             set { SetValue(TabCharsProperty, value); }
1905         }
1906
1907         /// <summary>
1908         /// TabCharsの依存プロパティを表す
1909         /// </summary>
1910         public static readonly DependencyProperty TabCharsProperty =
1911             DependencyProperty.Register("TabChars",
1912             typeof(int),
1913             typeof(FooTextBox),
1914             new FrameworkPropertyMetadata(4));
1915
1916         /// <summary>
1917         /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
1918         /// </summary>
1919         public bool RectSelectMode
1920         {
1921             get { return (bool)GetValue(RectSelectModeProperty); }
1922             set { SetValue(RectSelectModeProperty, value); }
1923         }
1924
1925         /// <summary>
1926         /// RectSelectModeの依存プロパティを表す
1927         /// </summary>
1928         public static readonly DependencyProperty RectSelectModeProperty =
1929             DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1930
1931         /// <summary>
1932         /// 折り返しの方法を指定する
1933         /// </summary>
1934         /// <remarks>
1935         /// 変更した場合、レイアウトの再構築を行う必要があります
1936         /// </remarks>
1937         public LineBreakMethod LineBreakMethod
1938         {
1939             get { return (LineBreakMethod)GetValue(LineBreakProperty); }
1940             set { SetValue(LineBreakProperty, value); }
1941         }
1942
1943         /// <summary>
1944         /// LineBreakMethodの依存プロパティを表す
1945         /// </summary>
1946         public static readonly DependencyProperty LineBreakProperty =
1947             DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None));
1948
1949
1950         /// <summary>
1951         /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
1952         /// </summary>
1953         /// <remarks>
1954         /// 変更した場合、レイアウトの再構築を行う必要があります
1955         /// </remarks>
1956         public int LineBreakCharCount
1957         {
1958             get { return (int)GetValue(LineBreakCharCountProperty); }
1959             set { SetValue(LineBreakCharCountProperty, value); }
1960         }
1961
1962         /// <summary>
1963         /// LineBreakCharCountの依存プロパティを表す
1964         /// </summary>
1965         public static readonly DependencyProperty LineBreakCharCountProperty =
1966             DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));
1967
1968         /// <summary>
1969         /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1970         /// </summary>
1971         public bool DrawCaret
1972         {
1973             get { return (bool)GetValue(DrawCaretProperty); }
1974             set { SetValue(DrawCaretProperty, value); }
1975         }
1976
1977         /// <summary>
1978         /// DrawCaretの依存プロパティを表す
1979         /// </summary>
1980         public static readonly DependencyProperty DrawCaretProperty =
1981             DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(true));
1982
1983         
1984         /// <summary>
1985         /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1986         /// </summary>
1987         public bool DrawCaretLine
1988         {
1989             get { return (bool)GetValue(DrawCaretLineProperty); }
1990             set { SetValue(DrawCaretLineProperty, value); }
1991         }
1992
1993         /// <summary>
1994         /// DrawCaretLineの依存プロパティを表す
1995         /// </summary>
1996         public static readonly DependencyProperty DrawCaretLineProperty =
1997             DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1998
1999         /// <summary>
2000         /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
2001         /// </summary>
2002         public bool DrawLineNumber
2003         {
2004             get { return (bool)GetValue(DrawLineNumberProperty); }
2005             set { SetValue(DrawLineNumberProperty, value); }
2006         }
2007
2008         /// <summary>
2009         /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
2010         /// </summary>
2011         public bool DrawRuler
2012         {
2013             get { return (bool)GetValue(DrawRulerProperty); }
2014             set { SetValue(DrawRulerProperty, value); }
2015         }
2016
2017         /// <summary>
2018         /// DrawRulerの依存プロパティを表す
2019         /// </summary>
2020         public static readonly DependencyProperty DrawRulerProperty =
2021             DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
2022
2023         
2024         /// <summary>
2025         /// DrawLineNumberの依存プロパティを表す
2026         /// </summary>
2027         public static readonly DependencyProperty DrawLineNumberProperty =
2028             DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
2029
2030         /// <summary>
2031         /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
2032         /// </summary>
2033         public bool MarkURL
2034         {
2035             get { return (bool)GetValue(MarkURLProperty); }
2036             set { SetValue(MarkURLProperty, value); }
2037         }
2038
2039         /// <summary>
2040         /// MarkURLの依存プロパティを表す
2041         /// </summary>
2042         public static readonly DependencyProperty MarkURLProperty =
2043             DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
2044
2045         /// <summary>
2046         /// 全角スペースを表示するなら真。そうでないなら偽
2047         /// </summary>
2048         public bool ShowFullSpace
2049         {
2050             get { return (bool)GetValue(ShowFullSpaceProperty); }
2051             set { SetValue(ShowFullSpaceProperty, value); }
2052         }
2053
2054         /// <summary>
2055         /// ShowFullSpaceの依存プロパティを表す
2056         /// </summary>
2057         public static readonly DependencyProperty ShowFullSpaceProperty =
2058             DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
2059
2060         /// <summary>
2061         /// 半角スペースを表示するなら真。そうでないなら偽
2062         /// </summary>
2063         public bool ShowHalfSpace
2064         {
2065             get { return (bool)GetValue(ShowHalfSpaceProperty); }
2066             set { SetValue(ShowHalfSpaceProperty, value); }
2067         }
2068
2069         /// <summary>
2070         /// ShowHalfSpaceの依存プロパティを表す
2071         /// </summary>
2072         public static readonly DependencyProperty ShowHalfSpaceProperty =
2073             DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
2074
2075         /// <summary>
2076         /// タブを表示するなら真。そうでないなら偽
2077         /// </summary>
2078         public bool ShowTab
2079         {
2080             get { return (bool)GetValue(ShowTabProperty); }
2081             set { SetValue(ShowTabProperty, value); }
2082         }
2083
2084         /// <summary>
2085         /// ShowTabの依存プロパティを表す
2086         /// </summary>
2087         public static readonly DependencyProperty ShowTabProperty =
2088             DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
2089
2090         /// <summary>
2091         /// 改行マークを表示するなら真。そうでないなら偽
2092         /// </summary>
2093         public bool ShowLineBreak
2094         {
2095             get { return (bool)GetValue(ShowLineBreakProperty); }
2096             set { SetValue(ShowLineBreakProperty, value); }
2097         }
2098
2099         /// <summary>
2100         /// ShowLineBreakの依存プロパティを表す
2101         /// </summary>
2102         public static readonly DependencyProperty ShowLineBreakProperty =
2103             DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
2104         
2105         #endregion
2106     }
2107     /// <summary>
2108     /// マウスボタン関連のイベントクラス
2109     /// </summary>
2110     public sealed class FooMouseButtonEventArgs : MouseButtonEventArgs
2111     {
2112         /// <summary>
2113         /// イベントが発生したドキュメントのインデックス
2114         /// </summary>
2115         public int Index
2116         {
2117             get;
2118             private set;
2119         }
2120
2121         /// <summary>
2122         /// コンストラクター
2123         /// </summary>
2124         /// <param name="mouse">マウスデバイス</param>
2125         /// <param name="timestamp">タイムスタンプ</param>
2126         /// <param name="button">ボタン</param>
2127         /// <param name="stylusDevice">スタイラスデバイス</param>
2128         /// <param name="index">インデックス</param>
2129         public FooMouseButtonEventArgs(MouseDevice mouse, int timestamp, MouseButton button, StylusDevice stylusDevice, int index)
2130             : base(mouse, timestamp, button, stylusDevice)
2131         {
2132             this.Index = index;
2133         }
2134     }
2135     /// <summary>
2136     /// マウス関連のイベントクラス
2137     /// </summary>
2138     public sealed class FooMouseEventArgs : MouseEventArgs
2139     {
2140         /// <summary>
2141         /// イベントが発生したドキュメントのインデックス
2142         /// </summary>
2143         public int Index
2144         {
2145             get;
2146             private set;
2147         }
2148
2149         /// <summary>
2150         /// コンストラクター
2151         /// </summary>
2152         /// <param name="mouse">マウスデバイス</param>
2153         /// <param name="timestamp">タイムスタンプ</param>
2154         /// <param name="stylusDevice">スタイラスデバイス</param>
2155         /// <param name="index">インデックス</param>
2156         public FooMouseEventArgs(MouseDevice mouse,
2157             int timestamp,
2158             StylusDevice stylusDevice,
2159             int index)
2160             : base(mouse, timestamp, stylusDevice)
2161         {
2162             this.Index = index;
2163         }
2164     }
2165 }